1. 程式人生 > >springsecurity 登入form新增其他欄位(基於java配置)

springsecurity 登入form新增其他欄位(基於java配置)

在使用Spring Security框架過程中,經常會有這樣的需求,即在登入驗證時,附帶增加額外的資料,如驗證碼、使用者型別等。下面將介紹如何實現。

  注:我的工程是在Spring Boot框架基礎上的,使用xml方式配置的話請讀者自行研究吧。

  • 實現自定義的WebAuthenticationDetails

  該類提供了獲取使用者登入時攜帶的額外資訊的功能,預設實現WebAuthenticationDetails提供了remoteAddress與sessionId資訊。開發者可以通過Authentication的getDetails()獲取WebAuthenticationDetails。我們編寫自定義類CustomWebAuthenticationDetails繼承自WebAuthenticationDetails,新增我們關心的資料(以下是一個token欄位)。

複製程式碼
package com.cgs.courses.service;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.web.authentication.WebAuthenticationDetails;

public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {
    /**
     * 
     */
    private static final long serialVersionUID = 6975601077710753878L;
    
private final String token; public CustomWebAuthenticationDetails(HttpServletRequest request) { super(request); token = request.getParameter("token"); } public String getToken() { return token; } @Override public String toString() { StringBuilder sb
= new StringBuilder(); sb.append(super.toString()).append("; Token: ").append(this.getToken()); return sb.toString(); } }
複製程式碼

   注:在登入頁面,可將token欄位放在form表單中,也可以直接加在url的引數中,進而把額外資料傳送給後臺。

  • 實現自定義的AuthenticationDetailsSource

  該介面用於在Spring Security登入過程中對使用者的登入資訊的詳細資訊進行填充,預設實現是WebAuthenticationDetailsSource,生成上面的預設實現WebAuthenticationDetails。我們編寫類實現AuthenticationDetailsSource,用於生成上面自定義的CustomWebAuthenticationDetails。

複製程式碼
package com.cgs.courses.service;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;

@Component
public class CustomAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {

    @Override
    public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
        return new CustomWebAuthenticationDetails(context);
    }
}
複製程式碼
  • 配置使用自定義的AuthenticationDetailsSource

  只要看這一句.formLogin().authenticationDetailsSource(authenticationDetailsSource)

複製程式碼
    @Autowired
    private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource;

    protected void configure(HttpSecurity http) throws Exception {
        http
            .headers()
                .cacheControl()
                .contentTypeOptions()
                .httpStrictTransportSecurity()
                .xssProtection()
                .and()
            .authorizeRequests()
                .antMatchers(
                    "/css/**",
                    "/js/**")
                .permitAll()
                .antMatchers("/**")
                .authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .defaultSuccessUrl("/todo.html", true)
                .authenticationDetailsSource(authenticationDetailsSource)
            .and()
                .logout()
                .logoutUrl("/logout")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login")
                .and()
            .csrf().disable();
    }
複製程式碼
  • 實現自定義的AuthenticationProvider

  AuthenticationProvider提供登入驗證處理邏輯,我們實現該介面編寫自己的驗證邏輯。

複製程式碼
package com.cgs.courses.service;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
    
    @Override
    public Authentication authenticate(Authentication authentication) 
            throws AuthenticationException {
        CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) authentication.getDetails();  // 如上面的介紹,這裡通過authentication.getDetails()獲取詳細資訊
        // System.out.println(details); details.getRemoteAddress(); details.getSessionId(); details.getToken();
// 下面是驗證邏輯,驗證通過則返回UsernamePasswordAuthenticationToken,
// 否則,可直接丟擲錯誤(AuthenticationException的子類,在登入驗證不通過重定向至登入頁時可通過session.SPRING_SECURITY_LAST_EXCEPTION.message獲取具體錯誤提示資訊)
if (驗證通過) {
return UsernamePasswordAuthenticationToken(省略引數);
} else {
throw new AuthenticationException的子類("你要顯示的錯誤資訊")
}
} @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } }
複製程式碼
  • 配置使用自定義的AuthenticationProvider
複製程式碼
  @Autowired
    private AuthenticationProvider authenticationProvider;

  @Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(authenticationProvider); }