springboot集成shiro的简单实现

springboot集成shiro的简单实现


注意:
1.shiro需要自行在doGetAuthenticationInfo方法中进行账号密码的校验
2.ip+端口形式访问页面会被shiro拦截,如果没有登录会被重定向到login页面,如果登录会被重定向到index页面(需要配置)
3.登录成功后index页面跳转由shiro内部实现(需要配置)
4.退出登录操作由shiro内部实现(需要配置)
5.shiro的权限控制(按钮级别),为了在thymeleaf里使用shiro的标签的bean,需要在shiro中注入ShiroDialect(需要添加maven),否则无法进入doGetAuthorizationInfo方法!

流程:
当访问项目时会被shiro拦截进行登录校验,如果未登录会被重定向到登录页,如果登录直接放行方法(如果是ip+端口的形式访问会被重定向到首页)

方法:
获取shiro管理的对象方法:
User user = (User) SecurityUtils.getSubject().getPrincipal();

@Controller
public class LoginController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

//  首页跳转
    @GetMapping("/")
    String toIndex() {
        return "index";
    }

//  登录跳转
    @GetMapping("/login")
    String login() {
        return "login";
    }

//  登录
    @PostMapping("/ajaxLogin")
    @ResponseBody
    String ajaxLogin(String username, String password) {
        try {
            //收集实体/凭据信息
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
        } catch (Exception e) {
            return "error";
        }
        return "success";
    }
//  测试
    @GetMapping("/test")
    @RequiresPermissions("companyUser:user:save")
    String test(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("a", "a");
        redirectAttributes.addAttribute("b", "b");
        return "redirect:/test2";
    }

//  测试
    @GetMapping("/test2")
    @ResponseBody
    User test2(String a , String b ) {
        System.out.println("a:"+a +"----------"+"b:"+b );
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        return user;
    }

}
//自定义验证器(必要的)
public class MyRealm extends AuthorizingRealm {


    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        System.out.println("==================================================================授权");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //存放可放行的权限
        Set<String> str = new HashSet<>();
        str.add("companyUser:user:save");
        info.setStringPermissions(str);
        return info;
    }

    //验证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//        System.out.println("==================================================================验证");
        UsernamePasswordToken user = (UsernamePasswordToken) authenticationToken;
        char[] pd = user.getPassword();
        String password = String.valueOf(pd);
        String username = user.getUsername();
        if (!"admin".equals(username)||!"123456".equals(password)) {
            throw new IncorrectCredentialsException("账号或密码不正确");
        }
        User user = new User();
        user.setPassword(password);
        user.setUsername(username);
        //第一个参数用来存放在session中的信息
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        return info;
    }

}
//注入验证器(必要的)
@Configuration
public class ShiroConfiguration {

    //将自己的验证方式加入容器
    @Bean
    public MyRealm myShiroRealm() {
        MyRealm myRealm = new MyRealm();
        return myRealm;
    }

    /**
     * ShiroDialect,为了在thymeleaf里使用shiro的标签的bean
     * html中使用方法:shiro:hasPermission
     * Maven中添加:
     *          <dependency>
     *             <groupId>com.github.theborakompanioni</groupId>
     *             <artifactId>thymeleaf-extras-shiro</artifactId>
     *             <version>2.0.0</version>
     *         </dependency>
     *
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

    //权限管理,配置主要是Realm的管理认证
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //Filter工厂,设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> map = new HashMap<String, String>();
        //放行路径
        map.put("/ajaxLogin","anon");
        //登出
        map.put("/logout","logout");
        //对所有用户认证
        map.put("/**","authc");
        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //错误页面,认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //加入注解的使用,不加入这个注解不生效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}

登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form id="loginForm">
        账号:<input type="text" placeholder="请输入账号" name="username">
        密码:<input type="text" placeholder="请输入密码" name="password">
        <input type="button" id="loginBut" value="登录">
    </form>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
    $("#loginBut").click(function () {
        $.ajax({
            type: "POST",
            url: "/ajaxLogin",
            data: $("#loginForm").serialize(),
            success: function (r) {
                if ("success" == r) {
                    location.href="/"
                }else{
                    alert("账号或密码不正确!");
                }
            }
        });
    })
</script>
</html>

首页(权限测试页)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/test" shiro:hasPermission="companyUser:user:save">登录成功测试(有权限)</a>
    <a href="/test" >登录成功测试(无权限)</a>
</body>
</html>
//User对象
/**@Date注解
 * maven添加
 *         <dependency>
 *             <groupId>org.projectlombok</groupId>
 *             <artifactId>lombok</artifactId>
 *         </dependency>
 */
@Data
public class User implements Serializable {
    private String username;
    private String password;
}

猜你喜欢

转载自blog.csdn.net/qq_43639296/article/details/84034670