springboot集成shiro个人理解
1浏览器输入http://localhost:8072/shiro/时
2controller转发--跳转login页面
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
log.info("ShiroConfiguration拦截器启动");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器.
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/static/**", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
3 点击登录--
@RequestMapping("/login") public String login(HttpServletRequest request, Map<String, Object> map) throws Exception{ System.out.println("进入登录页"); // 登录失败从request中获取shiro处理的异常信息。 // shiroLoginFailure:就是shiro异常类的全类名. String exception = (String) request.getAttribute("shiroLoginFailure"); System.out.println("异常信息=" + exception); String msg = ""; if (exception != null) { if (UnknownAccountException.class.getName().equals(exception)) { System.out.println("UnknownAccountException -- > 账号不存在:"); msg = "UnknownAccountException -- > 账号不存在:";
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(Model model, String name, String password) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(name, password);
try {
subject.login(token);
Session session = subject.getSession();
session.setAttribute("shiroLoginFailure", subject);
return "redirect:index";
} catch (AuthenticationException e) {
model.addAttribute("error", "验证失败");
return "login";
}
4身份验证---开始
* 身份验证
**/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
log.info("进行身份验证");
//获取用户的输入的账号.
String username = (String) token.getPrincipal();
System.out.println(token.getCredentials());
//通过username从数据库中查找 User对象,如果找到,没找到.
//实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
AdminUserEntity adminUserEntity = adminUserService.findByUsername(username);
log.info("----->>adminUserEntity=" + adminUserEntity);
if (adminUserEntity == null) {
return null;
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
adminUserEntity, //用户名
adminUserEntity.getPassword(), //密码
ByteSource.Util.bytes(adminUserEntity.getCredentialsSalt()),//salt=username+salt
getName() //realm name
);
return authenticationInfo;
5 身份验证--开始--授权验证
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
log.info("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
AdminUserEntity adminUserEntity = (AdminUserEntity) principals.getPrimaryPrincipal();
List<String> permissions = adminUserService.findPermissionById(String.valueOf(adminUserEntity.getUid()));
String role = adminUserService.findRoleById(String.valueOf(adminUserEntity.getUid()));
authorizationInfo.addRole(role);
for (String p : permissions) {
authorizationInfo.addStringPermission(p);
}
System.out.println("--权限--" + permissions.toString());
return authorizationInfo;
6 验证通过跳转成功页面
1
2
3 4
4
5