-
- <dependency>
- <groupId>org.apache.shirogroupId>
- <artifactId>shiro-spring-boot-web-starterartifactId>
-
- <version>1.4.1version>
- dependency>
-
- <dependency>
- <groupId>com.github.theborakompanionigroupId>
- <artifactId>thymeleaf-extras-shiroartifactId>
- <version>2.0.0version>
- dependency>
1.application.properties
- #开启shiro
- shiro.web.enabled=true

- /**
- * MyRealm:资源授权和身份验证
- */
- @Component
- public class MyRealm extends AuthorizingRealm {
- //1.将MyRealm注册为bean,因为要调用service
- @Autowired
- private UserService userService;
- @Autowired
- private RoleService roleService;
- @Autowired
- private ResourceService resourceService;
-
- //资源授权
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
- //资源授权器
- SimpleAuthorizationInfo authorization = new SimpleAuthorizationInfo();
-
- //1.realm资源授权方法,从认证中获取封装的信息,
- User user = (User) principal.getPrimaryPrincipal();
-
- //2. 从数据库查询当前用户的角色列表,并转载到资源授权器里
- List
roles = roleService.getRolesByUserId(user.getId()); - //把当前用户的角色列表加入进资源授权器
- roles.stream().forEach(item ->{
- authorization.addRole(item.getRoleName());
-
- //3.在去数据库查询每个角色拥有的资源列表,并转载到资源授权器里
- List
resources = (List) resourceService.getResourceById(item.getId()); -
- //4.将角色列表和资源列表封装到资源授权器
- resources.stream().forEach(item2 ->{
- authorization.addStringPermission(item2.getPermission());
- });
-
- });
- return authorization;
- }
-
- //身份验证
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
- //1.获取用户名
- String userName = (String) token.getPrincipal();
-
- //2.通过用户名查找数据库的user信息,调用service
- User user = userService.getUserByUserName(userName);
- if (null == user){
- throw new UnknownAccountException("User name is not exit.");
- }
- //3.封装身份验证器,new SimpleAuthenticationInfo(Object principal, Object credentials, String realmName);
- return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
- }
- }
- @Configuration
- public class ShrioConfig {
-
- @Autowired
- private MyRealm myRealm;
-
-
- //组件安全管理器: securityManager
- @Bean
- public SecurityManager securityManager(){
- DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
- securityManager.setRealm(myRealm);
- return securityManager;
- }
-
- /**
- * -配置 shiro 过滤器工厂:ShiroFilterFactoryBean
- * -----------------
- * -拦截权限
- * anon:匿名访问,无需登录 ---- AnonymousFilter
- * authc:登录后才能访问 ---- FormAuthenticationFilter
- * user:登录过能访问 ---- UserFilter
- * logout:登出 ---- LogoutFilter
- * ------------------
- * URL匹配风格
- * ?:匹配一个字符,如 /admin? 将匹配 /admin1,但不匹配 /admin 或 /admin/
- * *:匹配零个或多个字符串,如 /admin* 将匹配 /admin 或/admin123,但不匹配 /admin/1
- * **:匹配路径中的零个或多个路径,如 /admin/** 将匹配 /admin/a 或 /admin/a/b
- * -----------------------
- * -方法名不能乱写,如果我们定义为别的名称,又没有添加注册过滤器的配置,
- * -那么 shiro 会加载 ShiroWebFilterConfiguration 过滤器,
- * -该过滤器会寻找 shiroFilterFactoryBean,找不到会抛出异常
- */
- //组件:shiro 过滤器工厂, ShiroFilterFactoryBean,需要注入安全管理器
-
- @Bean
- public ShiroFilterFactoryBean shiroFilterFactoryBean(){
- ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();
- //1.注入安全管理器
- filterFactory.setSecurityManager(securityManager());
- //2.设置登录页面和登录成功页面
- filterFactory.setLoginUrl("/login");
- filterFactory.setSuccessUrl("/test/thymeleafTest");
-
- //3.设置其余地址的访问规则,放在map中,key:通配符,value:访问策略
- /**
- * anon:匿名访问,无需登录 ---- AnonymousFilter
- * authc:登录后才能访问 ---- FormAuthenticationFilte
- * user:登录过能访问 ---- UserFilter
- * logout:登出 ---- LogoutFilter
- */
- Map
filterMap = new LinkedHashMap<>(); - //匿名策略:全部开放 anon:
- // 登录注册
- filterMap.put("/login","anon");
- filterMap.put("/register","anon");
- // 静态资源
- filterMap.put("/favicon.ico","anon");
- filterMap.put("/css/**","anon");
- filterMap.put("/images/**","anon");
- filterMap.put("/js/**","anon");
- filterMap.put("/vendors/**","anon");
- filterMap.put("/static/**","anon");
- // 测试模块
- filterMap.put("/test/**","anon");
- // api开发
- filterMap.put("/api/**","anon");
- //非匿名策略
- filterMap.put("/**","authc");
-
- //4.返回过滤器工厂
- filterFactory.setFilterChainDefinitionMap(filterMap);
- return filterFactory;
- }
-
- /**
- * - 注册shiro方言,让 thymeleaf 支持 shiro 标签
- */
- @Bean
- public ShiroDialect shiroDialect(){
- return new ShiroDialect();
- }
-
- /**
- * DefaultAdvisorAutoProxyCreator, Advisor 代理类生成器
- */
- @Bean
- @DependsOn({"lifecycleBeanPostProcessor"})
- public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
- DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
- advisorAutoProxyCreator.setProxyTargetClass(true);
- return advisorAutoProxyCreator;
- }
-
- /**
- * - 创建 AuthorizationAttributeSourceAdvisor,扫描 Shiro 注解
- */
- @Bean
- public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
- AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
- authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
- return authorizationAttributeSourceAdvisor;
- }
-
-
- }
- @Override
- @Transactional
- public Result
login(User user) { - //1. 得到subject----
- Subject subject = SecurityUtils.getSubject();
-
- //2. 封装一个令牌,装载用户名和密码------
- UsernamePasswordToken token = new UsernamePasswordToken(
- user.getUserName(),
- MD5Util.getMD5(user.getPassword()));
-
- //3. subject.login(令牌)----
- try {
- //令牌,身份认证和资源授权
- subject.login(token);
- subject.checkRole();
-
- //获取当前用户,并设置到session中
- //获取MyRealm认证返回的user
- User temp = (User) subject.getPrincipal();
- //返回apache的session
- Session session = subject.getSession();
- session.setAttribute("user",temp);
- return new Result<>(Result.ResultStatus.SUCCESS.code,"SUCCESS",temp);
- } catch (Exception e) {
- e.printStackTrace();
- LOGGER.debug(e.getMessage());
- return new Result<>(Result.ResultStatus.FAILD.code,e.getMessage());
- }
- }