shiro+thymeleaf简单案例

Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证,授权,企业会话管理和加密等。
核心主键:
UsernamePasswordToken
SecurityManager 负责安全认证和授权
Subject 访问系统的用户,主体
Realm 需要继承 AuthorizingRealm 类
AuthenticationInfo 用户认证
AuthorizationInfo 用户授权
DefaultWebSecurityManager 安全管理器自定义realm需要注入到进来
ShiroFilterFactoryBean 过滤器工厂
Principal:身份信息
在这里插入图片描述

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

realm

public class AccountRealm extends AuthorizingRealm {

    @Autowired
    private AccountService accountService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    /**
     * 认证
     * 登录
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取用户携带的token,客户端将user信息封装到token
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        //或者
//      String username = (String) authenticationToken.getPrincipal();
        //用户名验证,是否存在
        Account account = accountService.findByUsername(token.getUsername());
        if(account!=null){
            //shiro密码验证,是否正确
            return new SimpleAuthenticationInfo(account,account.getPassword(),getName());
            //shiro密码验证,有盐,是否正确
//            return new SimpleAuthenticationInfo(account,account.getPassword(), ByteSource.Util.bytes(account.getSalt()),getName());
        }
        return null;
    }
}

编写认证和授权规则

认证过滤器

anon:无需认证
authc:必须认证
user: 不一定要通过认证,曾经被shiro记录,如记住我
authcBasic:需要HTTPBasic认证

授权过滤器

perms:必须拥有某个权限才能访问
role: 必须拥有某个角色才能访问
port: 请求端口必须未指定值
rest:请求必须基于RESTful格式
ssl:必须是安全的RUL请求,HTTPS请求

/****************************************************/
创建3个页面
main.html、manage.html、admin.html
访问权限
1、必须登录才能访问mian
2、当前用户必须拥有manage权限授权才能访问manage。html
3、当前用户必须拥有admin角色才能访问admin.html


@Controller
public class AccountController {

    @GetMapping("/{url}")
    public String redirect(@PathVariable("url")String url){
        return url;
    }

    /**
     * 登录
     * form表单提交不能用restful
     *
     */
    @PostMapping("login")
    public String login(String username, String password, Model model){
        //subject与shiro进行交互
        Subject subject = SecurityUtils.getSubject();
        //token封装用户信息
        UsernamePasswordToken toekn = new UsernamePasswordToken(username, password);
        //shiro开始登录验证
        try {
            subject.login(toekn);
            //principal登录时存入的用户信息,可直接获取
            Account account = (Account)subject.getPrincipal();
            subject.getSession().setAttribute("account", account);
            return "index";
        } catch (UnknownAccountException e) {
            model.addAttribute("msg","用户不存在");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码不正确");
            return "login";
        }
    }

    @GetMapping("/unauth")
    @ResponseBody
    public String unauth(){
        return "权限不足";
    }

    @GetMapping("/logout")
    public String logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "login";
    }

}

public class AccountRealm extends AuthorizingRealm {

    @Autowired
    private AccountService accountService;

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前用户信息
        Subject subject = SecurityUtils.getSubject();
        //principal登录时存入的用户信息,可直接获取
        Account account = (Account)subject.getPrincipal();
        //设置角色
        Set<String> roles = new HashSet<>();
        roles.add(account.getRole());
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roles);
        //设置权限
        authorizationInfo.addStringPermission(account.getPerms());
        return authorizationInfo;
    }

    /**
     * 认证
     * 登录
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取用户携带的token,客户端将user信息封装到token
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        //用户名验证,是否存在
        Account account = accountService.findByUsername(token.getUsername());
        //如果 token 未封装user
//        String username = (String) authenticationToken.getPrincipal();
//        Account account = accountService.findByUsername(username);
        if(account!=null){
            //shiro密码验证,是否正确
            //account登录成功存入Subject中Object principal
            return new SimpleAuthenticationInfo(account,account.getPassword(),getName());
            //shiro密码验证,有盐,是否正确
//            return new SimpleAuthenticationInfo(account,account.getPassword(), ByteSource.Util.bytes(account.getSalt()),getName());
        }
        return null;
    }
}

  /**
     * 过滤器工厂
     * @Qualifier("securityManager") 将securityManager从spring中取出
     * @Bean(“shiroFilterFactoryBean”)可加可不加
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        //权限设置
        Map<String,String> map = new HashMap<>();
        map.put("/main", "authc");// authc 必须登录
        map.put("/manage", "perms[manage]");// perms 必须有manage权限
        map.put("/admin", "roles[admin]");// roles 必须有admin角色
        factoryBean.setFilterChainDefinitionMap(map);
        //设置登录页面
        factoryBean.setLoginUrl("/login");
        //设置未授权页面
        factoryBean.setUnauthorizedUrl("/unauth");
        return factoryBean;
    }

在这里插入图片描述
index

<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.com">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="#"/>
</head>
<body>
<h1>index</h1>
<div th:if="${session.account != null}">
    <span th:text="${session.account.username}">欢迎回来</span><a href="/logout">退出</a>
</div>
<a href="/main">main</a>||<a href="/manage">manage</a>||<a href="admin">admin</a>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值