工具:idea+maven
maven
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
shiro
Realm
/**
* @author : white.hou
* @description : 關聯管理員用戶的Realm
* @date: 2018/11/10_19:49
*/
public class RootRealm extends AuthorizingRealm {
@Autowired
private RootService rootService;
/**
* 執行認證邏輯
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
Logger loggerAuthenticationInfo =LoggerFactory.getLogger(getClass());
loggerAuthenticationInfo.info("執行認證邏輯");
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
/**
* 判斷接收到的信息
*/
loggerAuthenticationInfo.debug("獲取到的賬號: " + usernamePasswordToken.getUsername() + "," + "獲取到的密碼: " + Arrays.toString(usernamePasswordToken.getPassword()));
Root root=rootService.findRootTokenByRootName(usernamePasswordToken.getUsername());
if (root == null) {
/**
* Shiro底層返回 UnknownAccountException
*/
return null;
}
/**
* 判斷密碼
*/
return new SimpleAuthenticationInfo(root, root.getPassword(), "");
}
/**
* 資源授權
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
Logger loggerAuthorizationInfo =LoggerFactory.getLogger(getClass());
loggerAuthorizationInfo.info("執行授權邏輯");
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
Subject subject=SecurityUtils.getSubject();
Root root=(Root)subject.getPrincipal();
Root dbRoot=rootService.findRootTokenByRootName(root.getRootName());
simpleAuthorizationInfo.addStringPermission(dbRoot.getIdentity());
loggerAuthorizationInfo.debug("獲取到的數據庫對象的名字是: "+root.getRootName()+"獲取到的數據庫對象的身份標識是: "+root.getIdentity());
return simpleAuthorizationInfo;
}
}
config
/**
* @author : white.hou
* @description : shiro配置類
* @date: 2018/11/10_19:49
*/
@Configuration
public class ShiroConfig {
/**
* 創建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
/**
* 關聯securityManager
*/
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
/**
* 添加Shiro內置過濾器
* 常用:
* anon:無需認證(登錄)就能訪問
* authc:必須認證才能訪問
* user:使用rememberMe功能可以直接訪問
* perms:該資源必須得到資源權限才能訪問
* role:該資源必須得到角色權限才能訪問
*/
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/", "authc");
filterMap.put("/commons/*","authc");
// filterMap.put("/*/**","authc");
/**
* 添加授權邏輯 ,未獲得授權調轉到指定頁面
*/
filterMap.put("/user/*", "perms[user:root]");
filterMap.put("/root/*","perms[admin:root]");
/**
* 跳轉到指定頁面,參數爲@RequsetMapping
*/
shiroFilterFactoryBean.setLoginUrl("/tologin");
shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
/**
* 創建DefaultWebSecurityManager
* @param rootRealm
* @return
*/
@Bean(name = "defaultWebSecurityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("rootRealm") RootRealm rootRealm){
DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
/**
* 關聯Realm
*/
defaultWebSecurityManager.setRealm(rootRealm);
return defaultWebSecurityManager;
}
/**
* 創建RootRealm
* @return
*/
@Bean(name = "rootRealm")
public RootRealm getRootRealm(){
return new RootRealm();
}
}
contorller層
/**
* @author : white.hou
* @description : 登錄的controller 類
* @date: 2018/11/10_21:06
*/
@Controller
public class LoginController {
/**
* 登錄邏輯處理模塊
*/
@PostMapping("/login")
public String login(@RequestParam("rootName") String rootName, @RequestParam("password") String password, Model model) {
/**
* Shiro便攜認證操作:
* 1 獲取subject
* 2 封裝用戶數據
* 3 執行登錄方法
*/
org.apache.shiro.subject.Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(rootName, password);
try {
subject.login(usernamePasswordToken);
/* //界面優化的坑
model.addAttribute("rootIdentity",usernamePasswordToken.getUsername());*/
// 重定向
return "redirect:/main.html";
} catch (UnknownAccountException e) {
/**
* 登錄失敗:用戶名不存在
*/
model.addAttribute("msg", "用戶名不存在,請校驗後登錄");
return "/login";
} catch (IncorrectCredentialsException e) {
/**
* 登錄失敗:密碼錯誤
*/
model.addAttribute("msg", "密碼錯誤,請重新輸入");
return "/login";
}
}
/**
* 跳轉控制模塊
*/
@RequestMapping("/tologin")
public String tologin() {
return "/login";
}
/**
* 未授權頁面
*
* @return
*/
@RequestMapping("/noAuth")
public String noAuth() {
return "/noAuth";
}
}
頁面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="登錄">
<meta name="author" content="white.hou">
<title></title>
<!-- Bootstrap core CSS -->
<link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.1.3/css/bootstrap.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
<form class="form-signin" action="main.html" th:action="login" method="post">
<img class="mb-4" th:src="@{/asserts/img/bootstrap-solid.svg}" src="asserts/img/bootstrap-solid.svg" alt=""
width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<strong type="hidden" class="alert alert-warning" th:text="${msg}" th:if="${msg!=null}" >Warning!</strong>
<label class="sr-only" th:text="#{login.username}">Username</label>
<input type="text" name="rootName" class="form-control" placeholder="Username" th:placeholder="#{login.username}"
required="" autofocus="">
<label class="sr-only" th:text="#{login.password}">Password</label>
<input type="password" name="password" class="form-control" placeholder="Password"
th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"/> [[#{login.remember}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2018-2019</p>
<a class="btn btn-sm" th:href="@{login.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{login.html(l='en_US')}">English</a>
</form>
</body>
</html>
項目地址
springboot 集成 shiro的一個小demo](https://github.com/Hz12306/zjgsu_Swimcenter_manage.git)