四时宝库

程序员的知识宝库

Springboot+thymeleaf+Shiro继承,亲测可用

关于shiro的基本知识,以前的文章介绍过了,不再重复。直接上springboot+thymeleaf+shiro的集成代码。是我在项目中实际使用的,亲测可用。

1,引入依赖

注意版本,我的springboot是2.1.1.RELEASE

<!-- shiro -->
<dependency>
 <groupId>org.apache.shiro</groupId>
 <artifactId>shiro-all</artifactId>
 <version>1.2.5</version>
</dependency>
<!-- shiro end -->
<!--thymeleaf-shiro-extras-->
<dependency>
 <groupId>com.github.theborakompanioni</groupId>
 <artifactId>thymeleaf-extras-shiro</artifactId>
 <version>2.0.0</version>
</dependency>

2,shiro配置

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import java.util.LinkedHashMap;
import java.util.Map;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
@Configuration
public class ShiroConfig {
 @Bean
 public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
 // 必须设置 SecurityManager
 shiroFilterFactoryBean.setSecurityManager(securityManager);
 // setLoginUrl 如未登录,跳到登录页。如果不设置值,默认会自动寻找Web工程根目录下的"/login.jsp"页面 或 "/login" 映射
 shiroFilterFactoryBean.setLoginUrl("/notLogin");
 // 登录成功后的首页
 shiroFilterFactoryBean.setSuccessUrl("/index");
 // 设置无权限时跳转的 url;
 shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
 // 设置拦截器
 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
 // 静态资源获取,放开权限
 filterChainDefinitionMap.put("/static/**", "anon");
 //管理员页面,需要角色权限 “admin”
 filterChainDefinitionMap.put("/admin/**", "roles[admin]");
 //开放登陆、注册接口
 filterChainDefinitionMap.put("/login", "anon");
 filterChainDefinitionMap.put("/api/loginCheck", "anon");
 filterChainDefinitionMap.put("/api/register", "anon");
 //其余接口一律拦截
 // 主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截
// filterChainDefinitionMap.put("/**", "authc");
 filterChainDefinitionMap.put("/**", "anon");
 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
 System.out.println("Shiro拦截器工厂类注入成功");
 return shiroFilterFactoryBean;
 }
 /**
 * 注入 securityManager
 */
 @Bean
 public SecurityManager securityManager() {
 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
 // 设置realm.
 securityManager.setRealm(myShiroRealm());
 return securityManager;
 }
 @Bean
 public MyShiroRealm myShiroRealm(){
 MyShiroRealm myShiroRealm = new MyShiroRealm();
 // 我这里没使用cache,也可以不设置这个,只是log里会有个告警
 myShiroRealm.setAuthorizationCachingEnabled(false);
 return myShiroRealm;
 }
 // thymeleaf页面标签需要
 @Bean(name = "shiroDialect")
 public ShiroDialect shiroDialect(){
 return new ShiroDialect();
 }
}

3,自定义Realm

shiro做鉴权需要三个角色,user,role,和permission

分别对应用户、角色和权限

分别创建对应的bean,然后写一下查询和插入的方法。

import lombok.Data;
@Data
public class User {
 private Long id;
 private String username;
 private String password;
}
@Data
public class Role {
 private int id;
 private String rolename;
 private String username;
}
import com.yunsheng.filestore.entity.User;
import com.yunsheng.filestore.service.RoleService;
import com.yunsheng.filestore.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Set;
/**
 * Created by yys
 */
//@Component("myShiroRealm")
public class MyShiroRealm extends AuthorizingRealm {
 @Autowired
 private UserService userService;
 @Autowired
 private RoleService roleService;
 /**
 * 授权信息
 */
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
 //获取登录时输入的用户名
 String username = (String) principalCollection.getPrimaryPrincipal();
 if (username != null) {
 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
 Set<String> roles = roleService.getRoles(username);
 info.setRoles(roles);
 /** 权限还没用起来
 List<String> listUrl = permissionService.getTheUrl(username);//权限
 if (listUrl != null && !listUrl.isEmpty()) {
 for (String url : listUrl) {
 info.addStringPermission(url);//加入权限
 }
 }**/
 return info;
 }
 return null;
 }
 /**
 * 登录认证
 */
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
 String username = (String) authenticationToken.getPrincipal();
 User userByUsername = userService.getUserByUsername(username);
 if (null == userByUsername) {
 return null;
 }
 // 返回一个正确的用户认证信息即可
 return new SimpleAuthenticationInfo(userByUsername.getUsername(), userByUsername.getPassword(), "getName()");
 }
}

4,在登录鉴权时使用

 /**
 * 登录校验
 */
 @RequestMapping(value = "/api/loginCheck", method = RequestMethod.POST)
 @ResponseBody
 public Map<String, Object> loginCheck(@RequestBody Map<String, String> params) {
 String username = params.get("username");
 String password = params.get("password");
 //登录后存放进shiro token
 UsernamePasswordToken token = new UsernamePasswordToken(username, password);
 Subject subject = SecurityUtils.getSubject();
 try {
 subject.login(token);
 //根据权限,指定返回数据
 boolean admin = subject.hasRole("admin");
 if (admin){
 // 演示可以根据权限做不同的事情
 log.info("admin login");
 }
 } catch (AuthenticationException e) {
 e.printStackTrace();
 return ReturnApi.error("登录失败");
 }
 return ReturnApi.success("登录成功", null);
 }

5,在页面上使用

html头上加上:

<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="Thymeleaf"
 xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

使用:<shiro:principal/> 可显示登录的用户名

其他页面使用方法参考

<body>
 
<h3>index</h3>
 
<!-- 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。 -->
 
<p shiro:guest="">Please <a href="login.html">login</a></p>
 
<!-- 认证通过或已记住的用户。 -->
 
<p shiro:user="">
 
Welcome back John! Not John? Click <a href="login.html">here</a> to login.
 
</p>
 
<!-- 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。 -->
 
<p shiro:authenticated="">
 
Hello, <span shiro:principal=""></span>, how are you today?
 
</p>
 
<a shiro:authenticated="" href="updateAccount.html">Update your contact information</a>
 
<!-- 输出当前用户信息,通常为登录帐号信息。 -->
 
<p>Hello, <shiro:principal/>, how are you today?</p>
 
 
<!-- 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。 -->
 
<p shiro:notAuthenticated="">
 
Please <a href="login.html">login</a> in order to update your credit card information.
 
</p>
 
 
<!-- 验证当前用户是否属于该角色。 -->
 
<a shiro:hasRole="admin" href="admin.html">Administer the system</a><!-- 拥有该角色 -->
 
<!-- 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。 -->
 
<p shiro:lacksRole="developer"><!-- 没有该角色 -->
 
Sorry, you are not allowed to developer the system.
 
</p>
 
 
 
<!-- 验证当前用户是否属于以下所有角色。 -->
 
<p shiro:hasAllRoles="developer, 2"><!-- 角色与判断 -->
 
You are a developer and a admin.
 
</p>
 
 
 
<!-- 验证当前用户是否属于以下任意一个角色。 -->
 
<p shiro:hasAnyRoles="admin, vip, developer,1"><!-- 角色或判断 -->
 
You are a admin, vip, or developer.
 
</p>
 
 
 
<!--验证当前用户是否拥有指定权限。 -->
 
<a shiro:hasPermission="userInfo:add" href="createUser.html">添加用户</a><!-- 拥有权限 -->
 
 
 
<!-- 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。 -->
 
<p shiro:lacksPermission="userInfo:del"><!-- 没有权限 -->
 
Sorry, you are not allowed to delete user accounts.
 
</p>
 
 
 
<!-- 验证当前用户是否拥有以下所有角色。 -->
 
<p shiro:hasAllPermissions="userInfo:view, userInfo:add"><!-- 权限与判断 -->
 
You can see or add users.
 
</p>
 
 
 
<!-- 验证当前用户是否拥有以下任意一个权限。 -->
 
<p shiro:hasAnyPermissions="userInfo:view, userInfo:del"><!-- 权限或判断 -->
 
You can see or delete users.
 
</p>
 
<a shiro:hasPermission="pp" href="createUser.html">Create a new User</a>
 
</body>

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接