springBoot-整合shiro

引言:shiro是apache出的一个安全框架

废话不说,上代码,注释很详细

一、maven依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
     <groupId>org.apache.shiro</groupId>
     <artifactId>shiro-spring</artifactId>
     <version>1.2.5</version>
</dependency>
<dependency>
     <groupId>org.apache.shiro</groupId>
     <artifactId>shiro-ehcache</artifactId>
     <version>1.2.5</version>
</dependency>

二、自定义realm继承AuthorizingRealm

public class CustomRealm extends AuthorizingRealm {


    /**
     * 授权用户权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        // 获取用户
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 获取用户角色,实际项目从数据库查询
        Set<String> roleSet = new HashSet<String>();
        roleSet.add("admin");
        info.addRoles(roleSet);

        // 获取用户权限,实际项目从数据库查询
        Set<String> permissionSet = new HashSet<String>();
        permissionSet.add("user:add");
        permissionSet.add("user:find");
        info.addStringPermissions(permissionSet);
        return info;
    }

    /**
     * 认证-登录
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {

        if (authenticationToken.getPrincipal() == null) {
            return null;
        }

        // 1、从主体传过来的认证信息中,获得用户名
        String username = authenticationToken.getPrincipal().toString();
        User user = userMapper.findByuserName(username);
        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());

    }

三、配置shiro

@Configuration
public class ShiroConfig {

    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,因为在
     * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager Filter Chain定义说明
     *
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 设置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 登录的url
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后跳转的url
        shiroFilterFactoryBean.setSuccessUrl("/index");
        // 未授权url
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");

        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        // 定义filterChain,静态资源不拦截
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/fonts/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        // 配置退出过滤器,其中具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout");
        // 记得登录的接口也不需要拦截
        filterChainDefinitionMap.put("/submitLogin", "anon");
        // 除上以外所有url都必须认证通过才可以访问,未通过认证自动跳转到LoginUrl
        filterChainDefinitionMap.put("/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(shiroRealm());
        // 注入缓存管理器,这里暂时先不用
//        securityManager.setCacheManager(ehCacheManager());
        // 注入记住我管理器,这里暂时先不用
//        securityManager.setRememberMeManager(rememberMeManager());
        return securityManager;
    }

    @Bean
    public CustomRealm shiroRealm() {
        return new CustomRealm();//上面自定义的Realm
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }


    //这段代码为了支持shiro注解
    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator app = new DefaultAdvisorAutoProxyCreator();
        app.setProxyTargetClass(true);
        return app;
    }

}

四、controller

返回的视图就不贴了

@Controller
public class HomeController {

    @GetMapping("/")
    public String loginpage(ModelMap modelMap) {
        return "login";
    }

    @RequestMapping("/login")
    public String login(ModelMap modelMap, User user) {
        // 添加用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUserName(), user.getPassword());
        // 进行验证,这里可以捕获异常,然后返回对应信息
        try {
            subject.login(usernamePasswordToken);
        } catch (Exception e) {
            return "login";
        }
        return "index";
    }

    // 登出
    @RequestMapping(value = "/logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "login";
    }

    @RequestMapping(value = "/index")
    public String index() {
        return "index";
    }


    /**
    *
    * 注解表示拥有“user:add”权限才能访问,接收的是一个String数组
    * 如果是一个数组,默认表示拥有这个数组全部权限才能访问接口
    **/
    @RequiresPermissions({ "user:add" })
    @RequestMapping(value = "/add")
    public String test() {
        return "test";
    }

    /**
    *
    * 与上述相似,不同的是需要拥有这个角色才能访问
    * 第二个参数logical(可选值AND、OR):默认为AND表示需要全部角色,
    * 为OR不难理解拥有其中一个角色就行。
    * 上述的@RequiresPermissions注解logical参数也适用
    **/
    @RequiresRoles(value = { "admin","user" }, logical = Logical.OR)
    @RequestMapping(value = "/find")
    public String test1() {
        return "test";
    }

}

到这里就整合完毕了,欢迎大家相互交流。

                                                                                                      向上的路并不拥挤,而大多数人选择了安逸——it疯子也

发布了23 篇原创文章 · 获赞 41 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/feng_zi_ye/article/details/89504223