springboot整合shiro
shiro
GitHub:https://github.com/apache/shiro
与springboot整合
导入依赖:
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.5.3</version>
</dependency>
自定义Realm
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class UserRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermission("user:del");
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//假设已经从数据库获取数据
if(!"admin".equals(token.getUsername())) return null;
return new SimpleAuthenticationInfo("","admin","");
}
}
创建配置类ShiroConfig
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
/*
* Subject 用户
* SecurityManager 管理所有用户
* Realm 连接数据
* */
//ShiroFilterFactoryBean
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(securityManager);
//添加shiro的内置过滤器
/*
anon: 无需认证就可访问
authc:必须认证才能访问
user:必须拥有记住我功能才能访问
perms: 拥有对某个资源的权限才能访问
roles:拥有某个角色权限才能访问
*/
Map<String, String> filterMap = new LinkedHashMap<>();
//授权
filterMap.put("/user/add","perms[user:add]");
filterMap.put("/user/update","perms[user:update]");
//filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录界面
bean.setLoginUrl("/login");
//设置未授权页面
bean.setUnauthorizedUrl("/noauth");
return bean;
}
//DefaultWebSecurityManager
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建Realm,需自定义
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
授权详细写法:
过滤器 | 说明 | 示例 |
---|---|---|
anon | 没有参数,表示可以匿名使用 | /admins/**=anon |
authc | 表示需要认证(登录)才能使用,没有参数 | /admins/user/**=authc |
roles | 拥有某个角色权限才能访问,参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如:admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。 | /admins/user/**=roles[admin] |
perms | 拥有对某个资源的权限才能访问,参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,相当于isPermitedAll()方法。 | /admins/user/**=perms[user:add:*] |
rest | 根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。 | /admins/user/**=rest[post] |
port | 根据请求的端口 | /admins/user/**=port[8081] |
authcBasic | 没有参数表示httpBasic认证 | /admins/user/**=authcBasic |
ssl | ssl没有参数,表示安全的url请求,协议为https | /admins/user/**=ssl |
user | user没有参数表示必须存在用户,当登入操作时不做检查 | /admins/user/**=user |
注:anon,authcBasic,auchc,user是认证过滤器,perms,roles,ssl,rest,port是授权过滤器
Controller登录方法
//登录方法
@RequestMapping("/login")
public String login(String username,String password,Model model){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户登录数据
UsernamePasswordToken token =new UsernamePasswordToken(username,password);
try{
subject.login(token);
return "index";
}catch (UnknownAccountException e){//用户名不存在
model.addAttribute("msg","用户名错误");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误");
return "login";
}
}
整合thymeleaf
添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.0.0</version>
</dependency>
<!--shiro整合thymeleaf-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
在配置类ShiroConfig添加
//整合thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
简单使用
<!-- 开启提示需要在根标签html加上:xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro" -->
<!-- 判断是否有此权限 -->
<div shiro:hasPermission="user:add">
<a th:href="@{/user/add}">add</a>
</div>