2016-11-09 50 views
0

我正在編寫基於Spring Boot的後端應用程序沒有任何視圖(模板),因爲客戶端應用程序將使用它自己的HTML。
我試圖改變默認的行爲(HTTP POST)春季安全form-login認證 - 使用HTTP GETPOST。是的,我知道,這對安全有害,但這是要求。
我該怎麼做?春季安全授權在REST(或表單登錄)應用通過HTTP GET

我的應用程序:
應用

package net.company.rest; 

@EnableAutoConfiguration 
@ComponentScan 
public class Application { 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

SecurityConfig

package net.company.rest.config; 

@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private AuthSuccessHandler authSuccessHandler; 
    @Autowired 
    private AuthFailureHandler authFailureHandler; 
    @Autowired 
    private AuthEntryPoint authEntryPoint; 

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

     http.authorizeRequests().anyRequest().authenticated(); 
     http.exceptionHandling().authenticationEntryPoint(authEntryPoint); 

     http.formLogin().usernameParameter("user").passwordParameter("pass"); 
     http.formLogin().successHandler(authSuccessHandler).failureHandler(authFailureHandler); 

     http.logout().permitAll(); 

     http.cors(); 
     http.csrf().disable(); 
    } 

    // enable security 
    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     for (int i = 1; i <= 10; i++) { 
      auth.inMemoryAuthentication().withUser("user" + i).password("user" + i).roles("USER"); 
     } 
    } 
} 

AuthEntryPoint

package net.company.rest.component; 

@Component 
public class AuthEntryPoint implements AuthenticationEntryPoint { 

    @Override 
    public void commence(HttpServletRequest req, 
        HttpServletResponse resp, 
        AuthenticationException ex) throws IOException, ServletException { 

     resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
     UniversalMessage msg = new UniversalMessage(1, "not authenticated"); 
     try { 
      resp.getWriter().print(new ObjectMapper().writeValueAsString(msg)); 
     } catch (JsonProcessingException e) { 
      resp.getWriter().print(e.toString()); 
     } 
     resp.getWriter().flush(); 
    } 
} 

AuthSuccessHandler

package net.company.rest.component; 

@Component 
public class AuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { 

    @Override 
    public void onAuthenticationSuccess(HttpServletRequest req, 
            HttpServletResponse resp, 
            Authentication auth) throws ServletException, IOException { 

     resp.setStatus(HttpServletResponse.SC_OK); 
     UniversalMessage msg = new UniversalMessage(0, "auth success"); 
     try { 
      resp.getWriter().print(new ObjectMapper().writeValueAsString(msg)); 
     } catch (JsonProcessingException e) { 
      resp.getWriter().print(e.toString()); 
     } 
     resp.getWriter().flush(); 
     clearAuthenticationAttributes(req); 
    } 
} 

AuthFailureHandler

package net.company.rest.component; 
@Component 
public class AuthFailureHandler extends SimpleUrlAuthenticationFailureHandler { 

    @Override 
    public void onAuthenticationFailure(HttpServletRequest req, 
            HttpServletResponse resp, 
            AuthenticationException ex) throws IOException, ServletException { 

     resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
     UniversalMessage msg = new UniversalMessage(1, "auth error"); 
     try { 
      resp.getWriter().print(new ObjectMapper().writeValueAsString(msg)); 
     } catch (JsonProcessingException e) { 
      resp.getWriter().print(e.toString()); 
     } 
     resp.getWriter().flush(); 
    } 

} 

回答

0

的問題是,上面的代碼並沒有解決問題,login通過HTTP GET沒有反正工作。 沒有爲解決步驟:

  1. 添加新的類擴展UsernamePasswordAuthenticationFilter
package net.company.rest.config.web; 

@Slf4j 
public class AuthByGetFilter extends UsernamePasswordAuthenticationFilter { 

    public AuthByGetFilter() { 
     super(); 
     // change auth parameters 
     setUsernameParameter("user"); 
     setPasswordParameter("pass"); 

     // allow GET 
     setPostOnly(false); 
     setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "GET")); 
    } 

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

     SecurityContextHolder.clearContext(); 

     log.debug("Method: {}, Request: {}, params was hidden for security", request.getMethod(), request.getRequestURL()); 

     log.debug("Authentication request failed: {}", failed.toString()); 
     log.debug("Updated SecurityContextHolder to contain null Authentication"); 
     log.debug("Delegating to authentication failure handler " + getFailureHandler()); 

     getRememberMeServices().loginFail(request, response); 
     getFailureHandler().onAuthenticationFailure(request, response, failed); 

    } 

}  
  • 使用此類作爲過濾器在上述SecurityConfig
  • ... 
    
    // configure security 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
        http.addFilterBefore(authByGetFilter(), UsernamePasswordAuthenticationFilter.class); // add authByGetFilter 
        ... 
    } 
    
    // allow authentication by http GET method 
    @Bean 
    public AuthByGetFilter authByGetFilter() throws Exception { 
        AuthByGetFilter authByGetFilter = new AuthByGetFilter(); 
        authByGetFilter.setAuthenticationManager(authenticationManagerBean()); 
        authByGetFilter.setAuthenticationFailureHandler(authFailureHandler); 
        authByGetFilter.setAuthenticationSuccessHandler(authSuccessHandler); 
        return authByGetFilter; 
    } 
    
    ...