SpringBoot学习- 8、整合Shiro

SpringBoot学习足迹

Shiro是什么,引自百度百科:Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

关于Shiro网上讲的很多,以下代码是来自网上几篇博客文章的代码集成,

下面是集成步骤

1、pom.xml添加以下内容

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.3.2</version>
</dependency>

2、config包添加以下类,标蓝色行如果不写会有默认页面。

package com.jgui.config;

import com.jgui.shiro.CustomFormAuthenticationFilter;
import com.jgui.shiro.CustomRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Autowired
    CustomRealm customRealm;
    @Autowired
    CustomFormAuthenticationFilter customAuthenticationFilter;
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/webjars/**", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/front/**", "anon");
        filterChainDefinitionMap.put("/api/**", "anon");
        //filterChainDefinitionMap.put("/hello", "anon");

        filterChainDefinitionMap.put("/admin/**", "authc");
        filterChainDefinitionMap.put("/user/**", "authc");
        //主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;

    }

    @Bean
    public CustomFormAuthenticationFilter customAuthenticationFilter(){
        return new CustomFormAuthenticationFilter();
    }
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
        defaultSecurityManager.setRealm(new CustomRealm());
        return defaultSecurityManager;
    }

    @Bean
    public CustomRealm customRealm() {
        CustomRealm customRealm = new CustomRealm();
        return customRealm;
    }
}

3、当访问未授权的界面就会跳到/login 控制器对应的页面,如果我们使用前后端分离,那么就需要返回一个json,以下是一种实现方法

添加一个filter

package com.jgui.shiro;

import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONObject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.http.HttpStatus;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.Writer;

@Slf4j
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue){
        return false;
    }
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (isLoginRequest(request, response)) {
            if (!isLoginSubmission(request, response)) {
                if (log.isTraceEnabled()) {
                    log.trace("Attempting to access a path which requires authentication.  Forwarding to the " +
                            "Authentication url [" + getLoginUrl() + "]");
                }

                HttpServletResponse httpServletResponse = (HttpServletResponse) response;
                httpServletResponse.setContentType("application/json;charset=UTF-8");
                httpServletResponse.setStatus(HttpStatus.CONFLICT.value());
                JSONObject json = new JSONObject();
                json.put("message","没有权限访问");
                Writer writer = httpServletResponse.getWriter();
                writer.write(json.toJSONString());
                writer.flush();
                writer.close();
            }else {
                return executeLogin(request, response);
            }
        }
        return false;
    }

}

4、然后在ShiroConfig内添加如下代码

 // 自定义过滤器
        Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();

        filterMap.put("restful_return", customAuthenticationFilter);

        shiroFilterFactoryBean.setFilters(filterMap);

位置如下图

 

 

 5、这个时候返回的就是一个json了。

 6、以上内容参考博客

https://blog.csdn.net/weixin_33709219/article/details/91433272

https://blog.csdn.net/catoop/article/details/69210140

https://blog.csdn.net/cckevincyh/article/details/79629022

https://blog.csdn.net/nthack5730/article/details/51019516

上一篇:

SpringBoot学习- 7、问题Could not autowire. No beans of 'xxxx' type found处理

posted @ 2020-01-16 22:35  zhaogaojian  阅读(191)  评论(0编辑  收藏  举报