ngnix部署

Java注释以及字体颜色调节

  返回  

Shiro权限框架(2):搭建

2021/8/21 20:58:41 浏览:

一、引入依赖

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

二、将shiro交给Spring管理

1、托管Realm

    创建一个Realm继承AuthorizingRealm抽象,并实现该抽象类的两个方法(授权、验证)。

/**
 * 自定义Realm
 */
public class CustomRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        return null;
    }
}
/**
     * 将CustomRealm交给Spring管理
     * @return
     */
    @Bean
    public CustomRealm getCustomRealm() {
        return new CustomRealm();
    }

2、托管SecurityManager

 /**
     * 如果是web项目需要使用DefaultSecurityManager的子类DefaultWebSecurityManager
     * @return
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 将自定义Realm注入到securityManager中
        securityManager.setRealm(getCustomRealm());
        return securityManager;
    }

3、托管Subject

/**
     * @return
     */
    @Bean
    public Subject getSubject() {
        SecurityUtils.setSecurityManager(getDefaultWebSecurityManager());
        return SecurityUtils.getSubject();
    }

4、托管ShiroFilterFactoryBean

 /**
     * 托管 ShiroFilterFactoryBean
     * 必须设置name = shiroFilterFactoryBean
     * @return
     */
    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        // 注入SecurityManager
        shiroFilter.setSecurityManager(getDefaultWebSecurityManager());
        // 设置登录页面
        shiroFilter.setLoginUrl("/login.html");
        shiroFilter.setUnauthorizedUrl("/400.html");
        // 创建map存储放行的文件 注意顺序
        Map<String, String> map = new LinkedHashMap<>();
        // 添加放行文件 anon:表示可以匿名访问。 authc:表示需要认证才可以访问
        map.put("/login.html", "anon");
        map.put("/login", "anon");
        map.put("/**", "authc");
        shiroFilter.setFilterChainDefinitionMap(map);
        return shiroFilter;
    }

三、Shiro拦截AJAX的解决方案

1、Shiro的Filter拦截器

    因为Shiro是通过Servlet的Filter实现的,所以可以重写用户过滤器添加处理ajax的部分。Message类需要自行封装。

package com.example.demo.shiro;

import com.example.demo.pojo.Message;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.web.filter.authc.UserFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义用户拦截实现
 */
public class CustomUserFilter extends UserFilter {
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        resp.setCharacterEncoding("UTF-8");
        resp.setHeader("ContentType", "text/html;charset=UTF-8");
        String requestedWith = req.getHeader("X-Requested-With");
        // 判断该请求是否由ajax发出
        if ("XMLHttpRequest".equals(requestedWith)) {
            Message message = new Message();
            message.setCode(403);
            message.setMessage("请登录后操作");
            ObjectMapper mapper = new ObjectMapper();
            resp.getWriter().write(mapper.writeValueAsString(message));
        } else {
            this.saveRequestAndRedirectToLogin(request, response);
        }
        return false;
    }
}

    然后将自定义过滤器添加到ShiroFilterFactoryBean中。

 

四、启动测试

1、创建Controller

@RestController
public class LoginController {

    @RequestMapping("/login")
    public void Login() {
        System.out.println("进入到Login()");
    }

    @RequestMapping("/test")
    public void test(){
        System.out.println("进入到test()");
    }
}

2、创建页面(login.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/login">点击访问login</a>
    <a href="/test">点击访问test</a>
    <button id="login-btn"> 点击登录</button>
<script src="js/jquery.js"></script>
<script>
    $("#login-btn").click(function () {
       $.ajax({
           url:"/test",
           type:"post",
           dataType:"json",
           success:function (data) {
               console.log(data);
           }
       })
    });
</script>
</body>
</html>

    当点击访问/login可以正常访问,访问/test则会被重定向回该页面。使用ajax访问需要登录才能访问的请求时,将返回信息。

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号