springboot整合shiro與自定義過(guò)濾器的全過(guò)程
filter自定義過(guò)濾器 增加了 對(duì)驗(yàn)證碼的校驗(yàn)
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();
}
//用戶未登錄
/* @Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpSession session = httpServletRequest.getSession();
String kaptchaCode = (String) session.getAttribute(kaptcha);
String code = httpServletRequest.getParameter("code");
if(code!=null&&kaptchaCode!=null&&!kaptchaCode.equals(code)){
httpServletRequest.setAttribute("shiroLoginFailure","codeError");
return true;
}
return super.onAccessDenied(request, response);
}
*/
//用戶提交表單時(shí)候 創(chuàng)建的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是為了接收前臺(tái)發(fā)送過(guò)來(lái)的數(shù)據(jù)
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才能使用自定義的過(guò)濾器
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>();
//驗(yàn)證碼的路徑 不要跟下面需要認(rèn)證的寫(xiě)在一個(gè)路徑里 會(huì)被攔截的
map.put("/servlet/**", "anon");
//需要把要授權(quán)的URL 全部裝到filterChain中去過(guò)濾
UserInfo userInfo = userReposisty.findByUid(1);
for (Role role : userInfo.getRoles()) {
for (Permission permission : role.getPermissions()) {
if (permission.getUrl() != "") {
String permissions = "perms[" + permission.getPermission() + "]";
map.put(permission.getUrl(), permissions);
}
}
}
map.put("/user*/*", "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());
//會(huì)話管理
securityManager.setSessionManager(sessionManager());
return securityManager;
}
//密碼鹽 可以不必實(shí)現(xiàn) 因?yàn)橐话忝艽a可以自己定義自己的密碼加密規(guī)則
/* @Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");
hashedCredentialsMatcher.setHashIterations(2);
return hashedCredentialsMatcher;
}*/
//開(kāi)啟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");//數(shù)據(jù)庫(kù)異常處理
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注冊(cè)器 -----》驗(yàn)證碼的路徑
@Bean
public ServletRegistrationBean servletRegistrationBean() {
System.out.println("----驗(yàn)證碼---");
return new ServletRegistrationBean(new KaptchaServlet(), "/servlet/kaptcha.jpg");
}
//自定義過(guò)濾器 ---》里面實(shí)現(xiàn)了對(duì)驗(yàn)證碼校驗(yàn)
@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());
//可以設(shè)置shiro提供的會(huì)話管理機(jī)制
//defaultWebSessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
return defaultWebSessionManager;
}
//這里就是會(huì)話管理的操作類
@Bean
public SessionDAO sessionDAO() {
return new RedisSessionDao();
}
//這里需要設(shè)置一個(gè)cookie的名稱 原因就是會(huì)跟原來(lái)的session的id值重復(fù)的
@Bean
public SimpleCookie simpleCookie() {
SimpleCookie simpleCookie = new SimpleCookie("REDISSESSION");
return simpleCookie;
}
}Shiro中的權(quán)限控制
#需要同時(shí)擁有order:add和order:query權(quán)限才可以訪問(wèn) /order-add = perms["order:add","order:query"] #只需要order:del權(quán)限就可以訪問(wèn) /order-del = perms["order:del"]
perms表示的就是權(quán)限控制,中括號(hào)中就是需要訪問(wèn)等號(hào)之前路徑,需要的權(quán)限名稱。如果在使用Shiro過(guò)濾器的時(shí)候,不配置過(guò)濾器,就會(huì)使用默認(rèn)的過(guò)濾器。
以下是默認(rèn)權(quán)限過(guò)濾器的源碼。
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;
? ? }
}從上面的代碼可以看出,我們的配置會(huì)默認(rèn)被強(qiáng)轉(zhuǎn)為string類型的字符串?dāng)?shù)組。當(dāng)只有一個(gè)權(quán)限時(shí),會(huì)直接判斷有沒(méi)有該權(quán)限; 當(dāng)配置多個(gè)權(quán)限時(shí),從下面的代碼可以看出只用在請(qǐng)求url的用戶擁有所有的權(quán)限時(shí),才會(huì)返回true,否則就會(huì)被拒絕訪問(wèn)。
總結(jié)
到此這篇關(guān)于springboot整合shiro與自定義過(guò)濾器的文章就介紹到這了,更多相關(guān)springboot整合shiro與自定義過(guò)濾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java8新特性Stream流中anyMatch和allMatch和noneMatch的區(qū)別解析
這篇文章主要介紹了Java8新特性Stream流中anyMatch和allMatch和noneMatch的區(qū)別解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
注入jar包里的對(duì)象,用@autowired的實(shí)例
這篇文章主要介紹了注入jar包里的對(duì)象,用@autowired的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
java使用htmlparser提取網(wǎng)頁(yè)純文本例子
這篇文章主要介紹了java使用htmlparser提取網(wǎng)頁(yè)純文本例子,需要的朋友可以參考下2014-04-04
Java實(shí)現(xiàn)Excel批量導(dǎo)入數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)Excel批量導(dǎo)入數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08
詳解JAVA抓取網(wǎng)頁(yè)的圖片,JAVA利用正則表達(dá)式抓取網(wǎng)站圖片
這篇文章主要介紹了詳解JAVA抓取網(wǎng)頁(yè)的圖片,JAVA利用正則表達(dá)式抓取網(wǎng)站圖片,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2016-12-12
myeclipse安裝Spring Tool Suite(STS)插件的方法步驟
這篇文章主要介紹了myeclipse安裝Spring Tool Suite(STS)插件的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
spring-core組件詳解——PropertyResolver屬性解決器
這篇文章主要介紹了spring-core組件詳解——PropertyResolver屬性解決器,需要的朋友可以參考下2016-05-05
如何讀取properties或yml文件數(shù)據(jù)并匹配
這篇文章主要介紹了如何讀取properties或yml文件數(shù)據(jù)并匹配方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12

