springboot整合shiro的簡單實現
阿新 • • 發佈:2018-12-03
springboot整合shiro的簡單實現
注意:
1.shiro需要自行在doGetAuthenticationInfo方法中進行賬號密碼的校驗
2.ip+埠形式訪問頁面會被shiro攔截,如果沒有登入會被重定向到login頁面,如果登入會被重定向到index頁面(需要配置)
3.登入成功後index頁面跳轉由shiro內部實現(需要配置)
4.退出登入操作由shiro內部實現(需要配置)
5.shiro的許可權控制(按鈕級別),為了在thymeleaf裡使用shiro的標籤的bean,需要在shiro中注入ShiroDialect(需要新增maven),否則無法進入doGetAuthorizationInfo方法!
流程:
當訪問專案時會被shiro攔截進行登入校驗,如果未登入會被重定向到登入頁,如果登入直接放行方法(如果是ip+埠的形式訪問會被重定向到首頁)
方法:
獲取shiro管理的物件方法:
User user = (User) SecurityUtils.getSubject().getPrincipal();
@Controller
public class LoginController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// 首頁跳轉
@GetMapping ("/")
String toIndex() {
return "index";
}
// 登入跳轉
@GetMapping("/login")
String login() {
return "login";
}
// 登入
@PostMapping("/ajaxLogin")
@ResponseBody
String ajaxLogin(String username, String password) {
try {
//收集實體/憑據資訊
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Subject subject = SecurityUtils.getSubject();
subject.login(token);
} catch (Exception e) {
return "error";
}
return "success";
}
// 測試
@GetMapping("/test")
@RequiresPermissions("companyUser:user:save")
String test(RedirectAttributes redirectAttributes) {
redirectAttributes.addAttribute("a", "a");
redirectAttributes.addAttribute("b", "b");
return "redirect:/test2";
}
// 測試
@GetMapping("/test2")
@ResponseBody
User test2(String a , String b ) {
System.out.println("a:"+a +"----------"+"b:"+b );
User user = (User) SecurityUtils.getSubject().getPrincipal();
return user;
}
}
//自定義驗證器(必要的)
public class MyRealm extends AuthorizingRealm {
//授權
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// System.out.println("==================================================================授權");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//存放可放行的許可權
Set<String> str = new HashSet<>();
str.add("companyUser:user:save");
info.setStringPermissions(str);
return info;
}
//驗證
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// System.out.println("==================================================================驗證");
UsernamePasswordToken user = (UsernamePasswordToken) authenticationToken;
char[] pd = user.getPassword();
String password = String.valueOf(pd);
String username = user.getUsername();
if (!"admin".equals(username)||!"123456".equals(password)) {
throw new IncorrectCredentialsException("賬號或密碼不正確");
}
User user = new User();
user.setPassword(password);
user.setUsername(username);
//第一個引數用來存放在session中的資訊
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
return info;
}
}
//注入驗證器(必要的)
@Configuration
public class ShiroConfiguration {
//將自己的驗證方式加入容器
@Bean
public MyRealm myShiroRealm() {
MyRealm myRealm = new MyRealm();
return myRealm;
}
/**
* ShiroDialect,為了在thymeleaf裡使用shiro的標籤的bean
* html中使用方法:shiro:hasPermission
* Maven中新增:
* <dependency>
* <groupId>com.github.theborakompanioni</groupId>
* <artifactId>thymeleaf-extras-shiro</artifactId>
* <version>2.0.0</version>
* </dependency>
*
* @return
*/
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
//許可權管理,配置主要是Realm的管理認證
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
//Filter工廠,設定對應的過濾條件和跳轉條件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String,String> map = new HashMap<String, String>();
//放行路徑
map.put("/ajaxLogin","anon");
//登出
map.put("/logout","logout");
//對所有使用者認證
map.put("/**","authc");
//登入
shiroFilterFactoryBean.setLoginUrl("/login");
//首頁
shiroFilterFactoryBean.setSuccessUrl("/index");
//錯誤頁面,認證不通過跳轉
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
//加入註解的使用,不加入這個註解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
登入頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="loginForm">
賬號:<input type="text" placeholder="請輸入賬號" name="username">
密碼:<input type="text" placeholder="請輸入密碼" name="password">
<input type="button" id="loginBut" value="登入">
</form>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
$("#loginBut").click(function () {
$.ajax({
type: "POST",
url: "/ajaxLogin",
data: $("#loginForm").serialize(),
success: function (r) {
if ("success" == r) {
location.href="/"
}else{
alert("賬號或密碼不正確!");
}
}
});
})
</script>
</html>
首頁(許可權測試頁)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/test" shiro:hasPermission="companyUser:user:save">登入成功測試(有許可權)</a>
<a href="/test" >登入成功測試(無許可權)</a>
</body>
</html>
//User物件
/**@Date註解
* maven新增
* <dependency>
* <groupId>org.projectlombok</groupId>
* <artifactId>lombok</artifactId>
* </dependency>
*/
@Data
public class User implements Serializable {
private String username;
private String password;
}