spring security 4カスタムログイン認証コードの設定
18842 ワード
最近やったプロジェクトの中でspring securityを使って権限を管理しています.これまで接触したことがないので、インターネットで長い間資料を探して研究しました.記録したいです.securityのバージョンは4.2を使っています.ネット上の多くの文章はすでに3.xと4.xの違いを説明していると信じています.ここでは説明しません.以下に準備作業を説明します.
関連jarパッケージ、pomダウンロード:
設定:
次はsecurityの配置です.構成については、「名前空間」の方式と「java config」の方式に分けることができます.
ここで使用するのは名前空間の構成方法です.
関連jarパッケージ、pomダウンロード:
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-ldapartifactId>
<version>4.2.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-coreartifactId>
<version>4.2.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-webartifactId>
<version>4.2.2.RELEASEversion>
dependency>
本プロジェクトで使用しているユーザーは会社のldapから取得しているので、spring-security-ldapパッケージも入れています.設定:
次はsecurityの配置です.構成については、「名前空間」の方式と「java config」の方式に分けることができます.
ここで使用するのは名前空間の構成方法です.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:s="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
<s:http pattern="/images/**" security="none" />
<s:http pattern="/js/**" security="none" />
<s:http pattern="/css/**" security="none" />
<s:http use-expressions="true" auto-config='true'>
<s:intercept-url pattern="/loginPage" access="hasRole('ROLE_ANONYMOUS')" />
<s:intercept-url pattern="/**"
access="hasAnyRole('ROLE_OPER','ROLE_ADMIN')" />
<s:form-login login-page="/loginPage"
username-parameter="username"
password-parameter="password"
default-target-url='/homepage/index'
always-use-default-target='true' />
<s:csrf disabled="false" />
<s:logout logout-url="/logout" logout-success-url="/login" />
<s:custom-filter before="FORM_LOGIN_FILTER" ref="myFilter" />
s:http>
<beans:bean id="myFilter" class="com.onstar.bdif.common.filters.MySpecialAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="successHandler" />
<property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler" />
beans:bean>
<bean id="successHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/homepage/index" />
bean>
<bean id="simpleUrlAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/loginPage" />
bean>
<s:authentication-manager id="authenticationManager" erase-credentials="false">
<s:ldap-authentication-provider
user-details-class="inetOrgPerson" group-search-filter="uniqueMember={0}"
role-prefix="xx" group-search-base="ou=xx"
user-dn-pattern="uid={0},ou=user,ou=xx" server-ref="ldapContextSource" />
s:authentication-manager>
<s:ldap-server id="ldapContextSource"
url="ldap://xx.xx.xx.xx:xx/ou=xx,ou=xx,o=xx.com" />
beans>
プロジェクトには認証コードの機能が使用されており、フロントエンドのログインページにはパスワード暗号化の一つの方法が追加されていますので、上述のようにユーザー定義のfilterを挿入して検証コードを検証し、暗号化されていないパスワードを復元して、ldapの検証に役立てます.// UsernamePasswordAuthenticationFilter
public class MySpecialAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private Logger logger = LogManager.getLogger(MySpecialAuthenticationFilter.class);
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "bdifacun";
public static final String SPRING_SECURITY_FORM_BDIFACPWD_KEY = "bdifacpwd";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String bdifacpwdParameter = SPRING_SECURITY_FORM_BDIFACPWD_KEY;
private boolean postOnly = true;
//
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
HttpSession session = request.getSession();
String username = obtainUsername(request);
String bdifacpwd = obtainPassword(request);
//
String inputValidateCode = request.getParameter("inputValidateCode");
//
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(bdifacpwd)) {
session.setAttribute("errorMsg", " !");
throw new AuthenticationServiceException("username or bdifacpwd is not null!");
}else {
bdifacpwd = AesUtil.aesDecrypt(bdifacpwd, OnstarConstans.AES_LOGIN_KEY);
}
// session ,
String sessionCaptcha = (String) session.getAttribute("validateCode");
if (StringUtils.isEmpty(inputValidateCode) || StringUtils.isEmpty(sessionCaptcha)) {
session.setAttribute("errorMsg", " !");
throw new AuthenticationServiceException("the session validate is not null!");
}
// Sesion
session.removeAttribute("validateCode");
//
if (!sessionCaptcha.equalsIgnoreCase(inputValidateCode)) {
session.setAttribute("errorMsg", " !");
throw new AuthenticationServiceException("the validate is error!");
}
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, bdifacpwd);
setDetails(request, authRequest);
Authentication authen = null;
// ldap
try {
authen = this.getAuthenticationManager().authenticate(authRequest);
} catch (AuthenticationException failed) {
session.setAttribute("errorMsg", " !");
throw new AuthenticationServiceException("the validate is error!");
}
session.setAttribute("managerSession", username);
return authen;
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(bdifacpwdParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
}
以上でsecurity登録の検証コードとフロントエンドのカスタムパスワード暗号化の検証ができます.文章は簡潔ではありません.後で確認するためにメモしてください.