簡體   English   中英

具有3字段身份驗證和自定義登錄表單的Spring啟動安全性

[英]Spring boot security with 3 fields authentication and custom login form

我正在使用spring boot,我需要使用3字段身份驗證過程用戶名,密碼和公司標識符作為表單中的隱藏輸入來實現spring security。

我實現了一個自定義的usernamepasswordauthenticationfilter,但它似乎不足以設置安全配置。

編輯:

用戶似乎沒有經過身份驗證! 因為a可以訪問web配置中定義的經過身份驗證的請求

編輯2:

在我的自定義過濾器中,當輸入有效用戶時,它會在succesfulAuthentication上執行。 我缺少什么請給我任何幫助:(我在這里

@Repository
public class AuthenticationUserDetailsService implements UserDetailsService {

private static final Logger LOGGER = Logger.getLogger(AuthenticationUserDetailsService.class);

@Autowired
private UserRepository users;

private org.springframework.security.core.userdetails.User userdetails;

@Override
public UserDetails loadUserByUsername(String input) throws UsernameNotFoundException {
    // TODO Auto-generated method stub

    System.out.println(input);
    String[] split = input.split(":");
    if (split.length < 2) {
        LOGGER.debug("User did not enter both username and corporate domain.");
        throw new UsernameNotFoundException("no corporate identifier is specified");
    }
    String username = split[0];
    String corporateId = split[1];

    System.out.println("Username = " + username);
    System.out.println("Corporate identifier = " + corporateId);

    boolean enabled = true;
    boolean accountNonExpired = true;
    boolean credentialsNonExpired = true;
    boolean accountNonLocked = true;

    com.ubleam.corporate.server.model.User user;

    user = checkUserDetail(username, corporateId);

    if (user == null)
        throw new NotAuthorizedException("Your are not allowed to access to this resource");

    LOGGER.info("User email : " + user.getEmail() + "#User corporate : " + user.getCorporateId());

    userdetails = new User(user.getEmail(), user.getPassword(), enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthorities("ROLE_USER"));
    return userdetails;
}

/**
 * 
 * @param roles
 *            roles granted for user
 * @return List of granted authorities
 * 
 */

public List<GrantedAuthority> getAuthorities(String roles) {

    List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
    authList.add(new SimpleGrantedAuthority(roles));
    return authList;
}

/**
 * User authentication details from database
 * 
 * @param username
 *            to use for authentication
 * @param coporateId
 *            corporate identifier of user
 * @return found user in database
 */
private com.ubleam.corporate.server.model.User checkUserDetail(String username, String corporateId) {

    com.ubleam.corporate.server.model.User user = users.findByEmailAndCorporateId(username, corporateId);

    return user;
}

我的定制過濾器:

public class PlatformAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

private static final Logger LOGGER = Logger.getLogger(PlatformAuthenticationFilter.class);

private static final String LOGIN_SUCCESS_URL = "{0}/bleamcards/{1}/home";
private static final String LOGIN_ERROR_URL = "{0}/bleamcards/{1}/login?error";
private String parameter = "corporateId";
private String delimiter = ":";
private String corporateId;

@Override
protected String obtainUsername(HttpServletRequest request) {
    String username = request.getParameter(getUsernameParameter());
    String extraInput = request.getParameter(getParameter());

    String combinedUsername = username + getDelimiter() + extraInput;

    setCorporateId(extraInput);
    LOGGER.info("Combined username = " + combinedUsername);
    return combinedUsername;
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException {

    String contextPath = request.getContextPath();
    String url = MessageFormat.format(LOGIN_SUCCESS_URL, contextPath, corporateId);

    response.sendRedirect(url);
}

@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {

    String contextPath = request.getContextPath();
    String url = MessageFormat.format(LOGIN_ERROR_URL, contextPath, corporateId);

    response.sendRedirect(url);
}

public String getParameter() {
    return parameter;
}

public void setParameter(String corporateId) {
    this.parameter = corporateId;
}

public String getDelimiter() {
    return delimiter;
}

public void setDelimiter(String delimiter) {
    this.delimiter = delimiter;
}

public String getCorporateId() {
    return corporateId;
}

public void setCorporateId(String corporateId) {
    this.corporateId = corporateId;
}
}

最后是web安全配置:

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Inject
private AuthenticationManagerBuilder auth;
@Inject
private UserDetailsService userDS;

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests().antMatchers("/bleamcards/**/login", "/bleamcards/**/forgetpassword", "/bleamcards/**/register", "/css/**", "/js/**", "/images/**", "/webjars/**")
            .permitAll().anyRequest().authenticated().and().addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class).formLogin().loginPage("/login")
            .defaultSuccessUrl("/").permitAll().and().logout().permitAll();
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.eraseCredentials(false);
    auth.userDetailsService(userDS).passwordEncoder(new BCryptPasswordEncoder());

}

@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception {
    return auth.build();
}

@Bean
public PlatformAuthenticationFilter authenticationFilter() throws Exception {
    PlatformAuthenticationFilter authFilter = new PlatformAuthenticationFilter();
    authFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST"));
    authFilter.setAuthenticationManager(authenticationManager());
    authFilter.setUsernameParameter("username");
    authFilter.setPasswordParameter("password");
    authFilter.setParameter("corporateId");
    return authFilter;
}

@Override
protected UserDetailsService userDetailsService() {
    return userDS;
}

我希望用戶只能連接到各自公司平台的/ login / register / forgetpasswod網址

實際上我設法找到解決我的問題的方法。

我在successAuthentication上添加了successHandler失蹤! 並且對於不成功的身份驗證方法也是一個失敗的手柄。

這是我的新身份驗證過濾器:

public class TwoFactorAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

private static final String LOGIN_SUCCESS_URL = "{0}/bleamcards/{1}/home"; 
private static final String LOGIN_ERROR_URL = "{0}/bleamcards/{1}/login?error";
private String parameter = "corporateId";
private String delimiter = ":";
private String corporateId;


@Override
protected String obtainUsername(HttpServletRequest request) {
    String username = request.getParameter(getUsernameParameter());
    String extraInput = request.getParameter(getParameter());
    String combinedUsername = username + getDelimiter() + extraInput;

    setCorporateId(extraInput);
    System.out.println("Combined username = " + combinedUsername);
    return combinedUsername;
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain , Authentication authResult) throws IOException, ServletException {

    String contextPath = request.getContextPath();
    String url = MessageFormat.format(LOGIN_SUCCESS_URL, contextPath, corporateId);
    setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(url));
    super.successfulAuthentication(request, response, chain, authResult);

}

@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {

    String contextPath = request.getContextPath();
    String url = MessageFormat.format(LOGIN_ERROR_URL, contextPath, corporateId);
    setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler(url));

    super.unsuccessfulAuthentication(request, response, failed);
}

public String getParameter() {
    return parameter;
}

public void setParameter(String corporateId) {
    this.parameter = corporateId;
}

public String getDelimiter() {
    return delimiter;
}

public void setDelimiter(String delimiter) {
    this.delimiter = delimiter;
}

public String getCorporateId() {
    return corporateId;
}

public void setCorporateId(String corporateId) {
    this.corporateId = corporateId;
}
}

您是否檢查過您的AuthenticationUserDetailsService代碼是否已被執行? 如果框架沒有調用它,這意味着您的配置沒有正確掛鈎UserDetailsService 在你的WebSecurityConfig我認為你需要這樣:

@Bean
public AuthenticationManager getAuthenticationManager() throws Exception {
    return super.authenticationManagerBean(); //not return auth.build();
}

我建議你看看Stormpath的 這個分店。 在那里,他們正在配置Spring Boot以使用自定義AuthenticationProvider (類似於UserDetailsService )。 該模塊使用並依賴於其他Spring Security模塊

然后, 這個示例Spring安全示例 (請注意它不是Spring Boot,而只是Spring)將為您提供Spring Security Java Config完成方式的完整示例。 請注意,此Java Config擴展了這個實際隱藏了大部分實際內部配置的Java Config。

免責聲明,我是Stormpath的積極貢獻者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM