springboot整合shiro与自定义过滤器的全过程
短信预约 -IT技能 免费直播动态提醒
filter自定义过滤器 增加了 对验证码的校验
package com.youxiong.filter;
import com.youxiong.shiro.UsernamePasswordKaptchaToken;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class FormValid extends FormAuthenticationFilter {
private String kaptcha = "KAPTCHA_SESSION_KEY";
public FormValid() {
super();
}
//用户未登录
//用户提交表单时候 创建的token
@Override
protected AuthenticationToken createToken( ServletRequest request, ServletResponse response) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String code = (String) httpServletRequest.getParameter("kaptcha");
String host = getHost(request);
String username = getUsername(request);
String password = getPassword(request);
boolean rememberMe = isRememberMe(request);
System.out.println("create token--------------code------>one "+code);
return new UsernamePasswordKaptchaToken(username,password.toCharArray(),rememberMe,host,code);
}
}
自定义UsernamePassword是为了接收前台发送过来的数据
package com.youxiong.shiro;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import java.io.Serializable;
public class UsernamePasswordKaptchaToken extends UsernamePasswordToken {
private static final long serialVersionUID = 1L;
private String kaptcha;
public UsernamePasswordKaptchaToken(){
super();
}
public UsernamePasswordKaptchaToken(String username, char[] password, boolean rememberMe, String host, String kaptcha) {
super(username, password, rememberMe, host);
this.kaptcha = kaptcha;
}
public String getKaptcha() {
return kaptcha;
}
public void setKaptcha(String kaptcha) {
this.kaptcha = kaptcha;
}
}
shiro配置
package com.youxiong.config;
import com.google.code.kaptcha.servlet.KaptchaServlet;
import com.youxiong.dao.UserReposisty;
import com.youxiong.domain.Permission;
import com.youxiong.domain.Role;
import com.youxiong.domain.UserInfo;
import com.youxiong.filter.FormValid;
import com.youxiong.redis.JedisCacheManager;
import com.youxiong.redis.RedisSessionDao;
import com.youxiong.redis.RedisSessionListener;
import com.youxiong.redis.RediseSessionFactory;
import com.youxiong.shiro.MyShiroRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionFactory;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import javax.servlet.Filter;
import java.util.*;
@Configuration
public class ShiroConfig {
@Autowired
private UserReposisty userReposisty;
@Bean
public ShiroFilterFactoryBean createShiroFilter(SecurityManager securityManager) {
System.out.println("--------ShiroFilterFactoryBean-------");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, Filter> filterMap = new HashMap<>();
//map里面key值要为authc才能使用自定义的过滤器
filterMap.put("authc", formValid());
// can go to login
shiroFilterFactoryBean.setLoginUrl("/login.html");
//doLogin success go to page
shiroFilterFactoryBean.setSuccessUrl("/success.html");
//do not Unauthorized page
shiroFilterFactoryBean.setUnauthorizedUrl("/403.html");
Map<String, String> map = new LinkedHashMap<String, String>();
//验证码的路径 不要跟下面需要认证的写在一个路径里 会被拦截的
map.put("/servlet*", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
shiroFilterFactoryBean.setFilters(filterMap);
return shiroFilterFactoryBean;
}
//自己定义realm
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
//缓存管理
securityManager.setCacheManager(jedisCacheManager());
//会话管理
securityManager.setSessionManager(sessionManager());
return securityManager;
}
//密码盐 可以不必实现 因为一般密码可以自己定义自己的密码加密规则
//开启aop注解
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver
createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
mappings.setProperty("UnauthorizedException", "403");
r.setExceptionMappings(mappings); // None by default
r.setDefaultErrorView("error"); // No default
r.setExceptionAttribute("ex"); // Default is "exception"
//r.setWarnLogCategory("example.MvcLogger"); // No default
return r;
}
//servlet注册器 -----》验证码的路径
@Bean
public ServletRegistrationBean servletRegistrationBean() {
System.out.println("----验证码---");
return new ServletRegistrationBean(new KaptchaServlet(), "/servlet/kaptcha.jpg");
}
//自定义过滤器 ---》里面实现了对验证码校验
@Bean("myFilter")
public FormValid formValid() {
return new FormValid();
}
//jedis缓存
@Bean
public JedisCacheManager jedisCacheManager() {
return new JedisCacheManager();
}
@Bean
public SessionManager sessionManager() {
DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
defaultWebSessionManager.setSessionIdCookie(simpleCookie());
defaultWebSessionManager.setSessionDAO(sessionDAO());
//可以设置shiro提供的会话管理机制
//defaultWebSessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
return defaultWebSessionManager;
}
//这里就是会话管理的操作类
@Bean
public SessionDAO sessionDAO() {
return new RedisSessionDao();
}
//这里需要设置一个cookie的名称 原因就是会跟原来的session的id值重复的
@Bean
public SimpleCookie simpleCookie() {
SimpleCookie simpleCookie = new SimpleCookie("REDISSESSION");
return simpleCookie;
}
}
Shiro中的权限控制
#需要同时拥有order:add和order:query权限才可以访问
/order-add = perms["order:add","order:query"]
#只需要order:del权限就可以访问
/order-del = perms["order:del"]
perms表示的就是权限控制,中括号中就是需要访问等号之前路径,需要的权限名称。如果在使用Shiro过滤器的时候,不配置过滤器,就会使用默认的过滤器。
以下是默认权限过滤器的源码。
public class PermissionsAuthorizationFilter extends AuthorizationFilter {
public PermissionsAuthorizationFilter() {
}
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
Subject subject = this.getSubject(request, response);
String[] perms = (String[])mappedValue;
boolean isPermitted = true;
if (perms != null && perms.length > 0) {
if (perms.length == 1) {
if (!subject.isPermitted(perms[0])) {
isPermitted = false;
}
} else if (!subject.isPermittedAll(perms)) {
isPermitted = false;
}
}
return isPermitted;
}
}
从上面的代码可以看出,我们的配置会默认被强转为string类型的字符串数组。当只有一个权限时,会直接判断有没有该权限; 当配置多个权限时,从下面的代码可以看出只用在请求url的用户拥有所有的权限时,才会返回true,否则就会被拒绝访问。
总结
到此这篇关于springboot整合shiro与自定义过滤器的文章就介绍到这了,更多相关springboot整合shiro与自定义过滤器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341