国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

spring-security 登陸認(rèn)證之初次探究

2019-11-14 22:30:42
字體:
供稿:網(wǎng)友
sPRing-security 登陸認(rèn)證之初次探究

首先,希望還對 spring-security框架完全不懂的新手 下載下Git源碼。 引入到項目中。這個短文就是邊看源碼邊聊的。也會啟動下項目驗(yàn)證自己的推想。

一、登陸認(rèn)證的登陸配置項
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.ht"   username-parameter="username" passWord-parameter="password" login-processing-url="/j_spring_security_check"/> <logout logout-url="/logout.ht"/>

看到這個配置,其實(shí)就大略明白了。 這就像配置了一個control/Servlet, userName 參數(shù)名字為 ”name“,password 為”password“

然后校驗(yàn)用戶密碼,通過就跳轉(zhuǎn)的頁面為 index.ht 。

spring-security框架維護(hù)了一個過濾器鏈來提供服務(wù), 而<form-login/> 這個登陸配置項其實(shí)創(chuàng)建了一個名為UsernamePasswordAuthenticationFilter的過濾器 。

框架提供的這些過濾器,也包括<custom-filter/>配置的過濾器。都是通過假名有嚴(yán)格順序來執(zhí)行的。稍后詳細(xì)介紹自定義過濾器。

UsernamePasswordAuthenticationFilter :

正如我們配置的這些參數(shù),也會有默認(rèn)配置的 比如

usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY =“j_username”,

passwordParameter=“j_password”

默認(rèn)接受form請求地址 :j_spring_security_check ,

這些可配置的參數(shù),都會存在默認(rèn)參數(shù)。這些參數(shù)的讀取是在 Initializing Spring root WebapplicationContext 后,加載并且解析xml配置文件。然后初始化ioc 容器。形成上面所提的過濾器鏈。

二、簡單說一下解析xml 過程

HttpSecurityBeanDefinitionParser.parse() { filterChains.add(createFilterChain(element, pc)); }

createFilterChain方法會調(diào)用 AuthenticationConfigBuilder的構(gòu)造方法 初始化各種filter createFormLoginFilter(sessionStrategy, authenticationManager); 即為登錄配置信息xml的解析處理方法:

SecurityNamespaceHandler.parse(Element element, ParserContext pc)  //關(guān)鍵代碼:String name = pc.getDelegate().getLocalName(element); BeanDefinitionParser parser = parsers.get(name); 通過配置項的名字。以策略模式獲取到專用解析器 都實(shí)現(xiàn)自BeanDefinitionParser 接口, 通過父類的引用執(zhí)行子類的具體實(shí)現(xiàn)。調(diào)用這些子類的parse()方法eg:RememberMeBeanDefinitionParser,LogoutBeanDefinitionParser等、、
錯誤代碼不必看

<form-login/> 的解析在 FormLoginBeanDefinitionParser, 解析后拿到配置的參數(shù),然后初始化一個filter 。

不知道這個解析方法為啥沒有實(shí)現(xiàn)BeanDefinitionParser 。 本來不想貼代碼的。更想愿意讀的人自己下載源碼自己看。

xml解析地方

三、獲取登陸獲取賬號密碼

切面走到這個登陸過濾器的時候 UsernamePasswordAuthenticationFilter.attemptAuthentication() 的方法 會從request中,通過配置的userNameParam ,passwordParam 獲取 name password

然后構(gòu)造一個包裝了密碼賬號的對象: new UsernamePasswordAuthenticationToken(password,username)

然后調(diào)用接口 AuthenticationManager.authenticate() (認(rèn)證管理類中的一個實(shí)現(xiàn)類 ProviderManager的認(rèn)證方法

四、配置驗(yàn)證密碼的認(rèn)證管理類

配置認(rèn)證管理類AuthenticationManager 需要 給它提供了一個 user-service bean 來通過用戶名獲取用戶

這個userDetailProvider bean 需要實(shí)現(xiàn)UserDetailsService接口 提供一個 loadUserByUsername()方法。

配置項:

<security:authentication-manager alias="authenticationManager"><security:authentication-provider user-service-ref="userDetailProvider"/> </security:authentication-manager><bean id="userDetailProvider" class="com.hotent.web.security.provider.UserAuthProvider"/>

然后 從ProviderManager 中的 List<AuthenticationProvider> providers認(rèn)證策略都 拿出來 進(jìn)行認(rèn)證(虛)

AbstractUserDetailsAuthenticationProvider .authenticate()

retrieveUser() // 調(diào)用子類DaoAuthenticationProvider的實(shí)現(xiàn)方法

DaoAuthenticationProvider.retrieveUser() 會通過我之前配置的userDetailProvider.loadUserByUsername(username),獲取用戶,

然后preAuthenticationChecks.check(user); 校驗(yàn)用戶是否可用、鎖定、過期

然后調(diào)用additionalAuthenticationChecks()方法驗(yàn)證密碼。

五、配置 密碼加密方式

接著我登陸不上才發(fā)現(xiàn)沒有配置密碼的加密類型。隨便找了 個文檔。配了下、居然發(fā)現(xiàn)啟動不了,妹的。

還好我比較機(jī)智,找到了xsd校驗(yàn)文件

順利找到了正確配置方法,在authentication-provider element下、 有一個password-encoder xs:element

這個element 有個attribute<xs:attributeGroup ref="security:password-encoder.attlist"/>,這個想必就是spring-security所支持的所有加密類型了。那xml 就改成了 這樣

最終authenticationManager的配置 如下

<security:authentication-manager alias="authenticationManager"><!-- 鑒定管理類 -->          <security:authentication-provider  user-service-ref="userDetailProvider">             <security:password-encoder hash="sha-256"/>         </security:authentication-provider>      </security:authentication-manager>

其實(shí)很少有人這么傻著從校驗(yàn)文件 去查屬性的。 除了像我這種機(jī)智到二的人。 其實(shí)官方文檔說的很清楚,而且xml也會有提示。但是我抱著探究的態(tài)度還是直接看xsd。

這樣密碼加密校驗(yàn)就通過。

接著將成功登陸用戶,和用戶信息發(fā)布出一個事件

applicationEventPublisher.publishEvent(new AuthenticationSuccessEvent(authentication));

///

六、登陸的擴(kuò)展

很多時候,我們希望做更多的擴(kuò)展、比如加一些U盾之類的口令啦、短信校驗(yàn)啦。驗(yàn)證碼啦。 那么要實(shí)現(xiàn)、可以加些自定義的過濾器,也可以重寫一些方法,等等、初次探究,我現(xiàn)在還不夠清楚。 不過這些都略有些麻煩。

其實(shí)如果你自己去校驗(yàn)用戶。然后將用戶登錄信息放入SecurityContext 里面 也就可以隨心所欲了。

如下圖 驗(yàn)證賬號密碼、驗(yàn)證碼 的截圖略過!直接是驗(yàn)證密碼后的操作。

關(guān)鍵代碼

  UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, encrptPassword);  authRequest.setDetails(new WebAuthenticationDetails(request));  SecurityContext securityContext = SecurityContextHolder.getContext();  Authentication auth = authenticationManager.authenticate(authRequest);   securityContext.setAuthentication(auth);  sessionStrategy.onAuthentication(auth, request, response);   

注入要使用的類

  @Resource(name = "authenticationManager")    private AuthenticationManager authenticationManager = null;    @Resource    UserDetailsService userDetailsService;    @Resource    private SessionAuthenticationStrategy sessionStrategy= new NullAuthenticatedSessionStrategy();

注入的authenticationManager 其實(shí)就是之前寫到的 ProviderManager

我們直接使用用戶名,密碼(加密后) 構(gòu)建了UsernamePasswordAuthenticationToken(為存放密碼賬號信息的一個令牌) 是Authentication接口的一個實(shí)例。然后把構(gòu)建好的 authentication 發(fā)送給authenticationManager 進(jìn)行校驗(yàn) 。

authenticationManager 成功校驗(yàn)后,返回一個完全的 Authentication 實(shí)例。

SecurityContextHolder.getContext().setAuthentication(...)

Spring Security 并不知道你怎么把Authentication 對象 放到了SecurityContextHolder 里面,唯一關(guān)鍵點(diǎn)就是 “SecurityContextHolder 已經(jīng)包含了一個 Authentication 標(biāo)識了一個主體”。 這樣就能滿足AbstractSecurityInterceptor之前的驗(yàn)證一個用戶需要。

所以、這個authentication放入SecurityContextHolder的過程可以有很多種方式、一個過濾器、一個control方法、就能達(dá)到目的,自然就實(shí)現(xiàn)了登陸。

有空繼續(xù)


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 正阳县| 怀来县| 河间市| 鹤岗市| 柳林县| 崇阳县| 金堂县| 故城县| 南岸区| 唐河县| 左贡县| 揭东县| 凤山县| 滁州市| 霸州市| 德庆县| 手游| 桂阳县| 锦屏县| 抚州市| 微山县| 商丘市| 安龙县| 阳江市| 余姚市| 乾安县| 新丰县| 雅安市| 麻城市| 海阳市| 永嘉县| 察雅县| 虎林市| 长治市| 读书| 盘山县| 富裕县| 巴彦淖尔市| 集贤县| 碌曲县| 青冈县|