• Shiro简例


    目录

    UserRealm

    ApplicationContextRegister

    ShiroUtil

    UsernamePasswordToken

    SimpleAuthenticationInfo

    ShiroConfig


    UserRealm

    包含两个方法,用户的授权和登录认证。

    1. public class UserRealm extends AuthorizingRealm {
    2. //用户授权
    3. @Override
    4. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    5. //获取MenuService
    6. MenuService menuService = ApplicationContextRegister.getBean(MenuService.class);
    7. //获取用户id
    8. Long userId = ShiroUtils.getUserId();
    9. //获取该对象的权限列表
    10. Set<String> parms = menuService.getParms(userId);
    11. SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    12. for (String parm : parms) {
    13. info.addStringPermission(parm);
    14. }
    15. return info;
    16. }
    17. //登录认证
    18. @Override
    19. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    20. //包含用户输入的信息 如用户名和密码
    21. UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
    22. String userName = (String) usernamePasswordToken.getPrincipal();
    23. //从数据库中 根据用户名查询用户信息
    24. UserDao userDao = ApplicationContextRegister.getBean(UserDao.class);
    25. User u = userDao.getUserByUserName(userName);
    26. String password = new String(usernamePasswordToken.getPassword());
    27. if (u == null){
    28. throw new UnknownAccountException("账号或者密码不正确");
    29. }
    30. else if (!password.equals(u.getPassword())){
    31. throw new IncorrectCredentialsException("账号或密码不正确");
    32. }
    33. // 账号锁定
    34. if (u.getStatus() == 0) {
    35. throw new LockedAccountException("账号已被锁定,请联系管理员");
    36. }
    37. //user对象、数据库中的密码,当前类的名字
    38. return new SimpleAuthenticationInfo(u, u.getPassword(), getName());
    39. }
    40. }

    ApplicationContextRegister

    实现接口ApplicationContextAware ,获取Spring的ioc容器,方便获取java bean。

    1. @Repository
    2. public class ApplicationContextRegister implements ApplicationContextAware {
    3. private static Logger logger = LoggerFactory.getLogger(ApplicationContextAware.class);
    4. private static ApplicationContext APPLICATION_CONTEXT;
    5. @Override
    6. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    7. logger.info("applicationContext--->",applicationContext);
    8. APPLICATION_CONTEXT = applicationContext;
    9. }
    10. public static ApplicationContext getApplicationContext(){
    11. return APPLICATION_CONTEXT;
    12. }
    13. public static <T> T getBean(Class<T> type ){
    14. return APPLICATION_CONTEXT.getBean(type);
    15. }
    16. }

    ShiroUtil

    方便获取用户对象及信息

    1. public class ShiroUtils {
    2. public static Subject getSubject(){
    3. Subject subject = SecurityUtils.getSubject();
    4. return subject;
    5. }
    6. public static User getUser(){
    7. User user = (User) getSubject().getPrincipal();
    8. return user;
    9. }
    10. public static Long getUserId(){
    11. return getUser().getUserId();
    12. }
    13. public static void logout(){
    14. getSubject().logout();
    15. }
    16. }

    UsernamePasswordToken

    AuthenticationToken 用于收集用户提交的身份(如用户名)及凭据(如密码):

    1. public interface AuthenticationToken extends Serializable {
    2.     Object getPrincipal(); //身份 用户名
    3.     Object getCredentials(); //凭据 密码
    4. }


    扩展接口RememberMeAuthenticationToken:提供了“boolean isRememberMe()”现“记住我”的功能;

    扩展接口是HostAuthenticationToken:提供了“String getHost()”方法用于获取用户“主机”的功能。

    Shiro 提供了一个直接拿来用的UsernamePasswordToken,用于实现用户名/密码Token组,另外其实现了RememberMeAuthenticationToken和HostAuthenticationToken,可以实现记住我及主机验证的支持。
     

    1. getPrincipal 与 getUserName
    2. getCredentials 与 getPassword

     

    SimpleAuthenticationInfo

    密码验证,交予shiro做。将数据库中的密码和前端传回的密码进行匹配。

    1. //user对象、数据库中的密码,当前类的名字
    2. new SimpleAuthenticationInfo(u, u.getPassword(), getName());

    ShiroConfig

    shiro的配置文件,配置三个组件。

    ShiroFilterFactoryBean 、SecurityManager 、UserRealm 

    1. @Configuration
    2. public class ShiroConfig {
    3. @Bean
    4. ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
    5. ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    6. shiroFilterFactoryBean.setSecurityManager(securityManager);
    7. //设置登录失败,授权成功、授权失败之后的uri
    8. shiroFilterFactoryBean.setLoginUrl("/login");
    9. shiroFilterFactoryBean.setSuccessUrl("/index");
    10. shiroFilterFactoryBean.setUnauthorizedUrl("/403");
    11. //设置资源权限
    12. /*
    13. anon 无拦截
    14. authc 认证后登录
    15. user 拥有记住我访问
    16. perms 拥有某个资源权限权限
    17. role 拥有某个角色权限权限
    18. */
    19. LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
    20. filterChainDefinitionMap.put("/login","anon");
    21. filterChainDefinitionMap.put("/getVerify","anon");
    22. filterChainDefinitionMap.put("/css/**", "anon");
    23. filterChainDefinitionMap.put("/js/**", "anon");
    24. filterChainDefinitionMap.put("/fonts/**", "anon");
    25. filterChainDefinitionMap.put("/img/**", "anon");
    26. filterChainDefinitionMap.put("/docs/**", "anon");
    27. filterChainDefinitionMap.put("/druid/**", "anon");
    28. filterChainDefinitionMap.put("/upload/**", "anon");
    29. filterChainDefinitionMap.put("/files/**", "anon");
    30. filterChainDefinitionMap.put("/logout", "logout");
    31. filterChainDefinitionMap.put("/", "anon");
    32. filterChainDefinitionMap.put("/blog", "anon");
    33. filterChainDefinitionMap.put("/blog/open/**", "anon");
    34. filterChainDefinitionMap.put("/**", "authc");
    35. shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    36. return shiroFilterFactoryBean;
    37. }
    38. @Bean
    39. public SecurityManager securityManager(){
    40. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    41. securityManager.setRealm(userRealm());
    42. return securityManager;
    43. }
    44. @Bean
    45. UserRealm userRealm(){
    46. return new UserRealm();
    47. }
    48. // ShiroDialect 用来整合 shiro-thymeleaf整合
    49. @Bean
    50. public ShiroDialect getShiroDialect(){
    51. return new ShiroDialect();
    52. }
    53. }

    前端接收参数

    1. @PostMapping("/login")
    2. @ResponseBody
    3. public ResponseInfo login(String username, String password, String verify, HttpSession session,HttpServletRequest request){
    4. String key = (String) session.getAttribute(RandomValidateCodeUtil.RANDOMCODEKEY);
    5. System.out.println(key);
    6. if (verify.length() != 0 && verify != ""){
    7. if (verify.equals(key)){
    8. //加密
    9. String encrypt = MD5Utils.encrypt(username,password);
    10. UsernamePasswordToken token = new UsernamePasswordToken(username, encrypt);
    11. Subject subject = SecurityUtils.getSubject();
    12. //跳转到UserRealm中的用户登录中
    13. subject.login(token);
    14. logger.info("登录成功");
    15. return ResponseInfo.ok();
    16. }
    17. return ResponseInfo.error(1,"验证码错误");
    18. }else {
    19. logger.error("验证码错误");
    20. return ResponseInfo.error(1,"验证码不能为空!");
    21. }
    22. }

  • 相关阅读:
    1359:围成面积
    云计算介绍
    对于JSP原理以及源码的深入剖析与理解心得
    商城免费搭建之java商城 开源java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c
    MongoDB聚合运算符:$cond
    Xilinx FPGA DDR3设计(三)DDR3 IP核详解及读写测试
    Go-Excelize API源码阅读(十五)——SetSheetViewOptions
    Spring与Redis的整合&&Redis注解式缓存以及Redis雪崩等问题的解决
    得物App弱网诊断探索之路
    Feign配置应用
  • 原文地址:https://blog.csdn.net/qq_56800327/article/details/125606655