2016-07-31 5 views
5

मैं स्प्रिंग बूट, वेब और सुरक्षा के नवीनतम संस्करण के साथ एक कस्टम प्रमाणीकरण तर्क लागू करने की कोशिश कर रहा हूं, लेकिन मैं कुछ मुद्दों से जूझ रहा हूं। मैं सफलता के बिना समान प्रश्नों/ट्यूटोरियल में कई समाधानों की कोशिश कर रहा था या समझता हूं कि वास्तव में क्या होता है।स्प्रिंग कस्टम प्रमाणीकरण फ़िल्टर और प्रदाता नियंत्रक विधि का आविष्कार नहीं कर रहा है

मैं स्टेटलेस प्रमाणीकरण के साथ एक आरईएसटी एप्लीकेशन बना रहा हूं, यानी एक आरईएसटी एंडपॉइंट (/ वेब/ऑथ/लॉगिन) है जो उपयोगकर्ता नाम और पासवर्ड की अपेक्षा करता है और स्ट्रिंग टोकन देता है, जिसे तब अन्य सभी आरईएसटी एंडपॉइंट्स में उपयोग किया जाता है (/ एपीआई/**) उपयोगकर्ता की पहचान करने के लिए। मुझे एक कस्टम समाधान लागू करने की आवश्यकता है क्योंकि भविष्य में प्रमाणीकरण अधिक जटिल हो जाएगा और मैं वसंत सुरक्षा की मूल बातें समझना चाहता हूं।

टोकन प्रमाणीकरण प्राप्त करने के लिए, मैं एक स्वनिर्धारित फिल्टर और प्रदाता बना रहा हूं:

फिल्टर:

public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter { 

public TokenAuthenticationFilter() { 
    super(new AntPathRequestMatcher("/api/**", "GET")); 
} 

@Override 
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { 
    String token = request.getParameter("token"); 
    if (token == null || token.length() == 0) { 
     throw new BadCredentialsException("Missing token"); 
    } 

    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(token, null); 

    return getAuthenticationManager().authenticate(authenticationToken); 
} 
} 

प्रदाता:

@Component 
public class TokenAuthenticationProvider implements AuthenticationProvider { 
@Autowired 
private AuthenticationTokenManager tokenManager; 

@Override 
public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
    String token = (String)authentication.getPrincipal(); 
    return tokenManager.getAuthenticationByToken(token); 
} 

@Override 
public boolean supports(Class<?> authentication) { 
    return UsernamePasswordAuthenticationToken.class.equals(authentication); 
} 
} 

config:

@EnableWebSecurity 
@Order(1) 
public class TokenAuthenticationSecurityConfig extends WebSecurityConfigurerAdapter { 
@Autowired 
private TokenAuthenticationProvider authProvider; 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.antMatcher("/api/**") 
    .csrf().disable() 
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
    .and().addFilterBefore(authenticationFilter(), BasicAuthenticationFilter.class); 
} 

@Bean 
public TokenAuthenticationFilter authenticationFilter() throws Exception { 
    TokenAuthenticationFilter tokenProcessingFilter = new TokenAuthenticationFilter(); 
    tokenProcessingFilter.setAuthenticationManager(authenticationManager()); 
    return tokenProcessingFilter; 
} 

@Override 
public void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.authenticationProvider(authProvider); 
} 
} 

AuthenticationTokenManager प्रदाता में (और भी प्रवेश प्रक्रिया में) का इस्तेमाल किया:

@Component 
public class AuthenticationTokenManager { 
private Map<String, AuthenticationToken> tokens; 

public AuthenticationTokenManager() { 
    tokens = new HashMap<>(); 
} 

private String generateToken(AuthenticationToken authentication) { 
    return UUID.randomUUID().toString(); 
} 

public String addAuthentication(AuthenticationToken authentication) { 
    String token = generateToken(authentication); 
    tokens.put(token, authentication); 
    return token; 
} 

public AuthenticationToken getAuthenticationByToken(String token) { 
    return tokens.get(token); 
} 

}

क्या होता है: मैं अनुरोध में कोई मान्य टोकन जोड़कर कर रहा हूँ करने के लिए "/ API/bla "(जो कुछ जेसन लौटने वाला एक आरईएसटी नियंत्रक है)। फ़िल्टर और प्रदाता दोनों को बुलाया जाता है। समस्या है, ब्राउज़र को आरईएसटी नियंत्रक की अनुरोधित विधि का आह्वान करने के बजाय "/" पर रीडायरेक्ट किया गया है। ऐसा लगता है कि SaveRequestAwareAuthenticationSuccessHandler में, लेकिन यह हैंडलर क्यों उपयोग किया जा रहा है?

मैं

  • की कोशिश की एक खाली सफलता हैंडलर लागू करने के लिए, 200 स्थिति कोड में जिसके परिणामस्वरूप और अभी भी एक सरल GenericFilterBean में
  • प्रमाणीकरण करने के लिए नियंत्रक लागू नहीं और SecurityContextHolder माध्यम से प्रमाणीकरण की वस्तु की स्थापना .getContext()। सेट प्रमाणीकरण (प्रमाणीकरण) जिसके परिणामस्वरूप "खराब प्रमाण-पत्र" त्रुटि पृष्ठ होता है।

मैं समझना चाहता हूं कि टोकन को प्रमाणित करने के बाद मेरे नियंत्रक को क्यों नहीं बुलाया जा रहा है। इसके अलावा, क्या एक मानचित्र में इसे संग्रहीत करने के बजाय टोकन को स्टोर करने के लिए "स्प्रिंग" तरीका है, जैसे सुरक्षा कॉन्टेक्स्ट रेजोजिटरी के कस्टम कार्यान्वयन की तरह?

मैं वास्तव में किसी भी संकेत की सराहना करता हूं!

+1

इसके लिए कोई कामकाजी समाधान? हमारे पास एक ही समस्या है, और कोई संकेत या कामकाजी कोड अच्छा होगा। – tg44

उत्तर

0

एक छोटे से देर हो सकता है, लेकिन मैं एक ही समस्या हो रही थी और जोड़ने: चाल किया

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

मेरी AbstractAuthenticationProcessingFilter कार्यान्वयन के लिए।

संबंधित मुद्दे

 संबंधित मुद्दे