it-swarm.com.de

So deaktivieren Sie die Federsicherheit für bestimmte URLs

Ich verwende die zustandslose Federsicherheit, aber im Falle einer Anmeldung möchte ich die Federsicherheit deaktivieren 

antMatchers("/api/v1/signup").permitAll().

aber es funktioniert nicht, ich bekomme unten einen Fehler: 

 message=An Authentication object was not found in the SecurityContext, type=org.springframework.security.authentication.AuthenticationCredentialsNotFoundException

Ich denke, das bedeutet, dass Federsicherheitsfilter funktionieren

Die Reihenfolge meiner URL lautet immer "/ api/v1".

Meine Frühjahrskonfiguration ist

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

         http.
         csrf().disable().
         sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
         and().
         authorizeRequests().
         antMatchers("/api/v1/signup").permitAll().
         anyRequest().authenticated().
         and().
         anonymous().disable();
        http.addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
    }

Mein Authentifizierungsfilter ist

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = asHttp(request);
        HttpServletResponse httpResponse = asHttp(response);

        String username = httpRequest.getHeader("X-Auth-Username");
        String password = httpRequest.getHeader("X-Auth-Password");
        String token = httpRequest.getHeader("X-Auth-Token");

        String resourcePath = new UrlPathHelper().getPathWithinApplication(httpRequest);

        try {

            if (postToAuthenticate(httpRequest, resourcePath)) {            
                processUsernamePasswordAuthentication(httpResponse, username, password);
                return;
            }

            if(token != null){
                processTokenAuthentication(token);
            }
            chain.doFilter(request, response);
        } catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
            SecurityContextHolder.clearContext();
            logger.error("Internal authentication service exception", internalAuthenticationServiceException);
            httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } catch (AuthenticationException authenticationException) {
            SecurityContextHolder.clearContext();
            httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
        } finally {
        }
    }

     private HttpServletRequest asHttp(ServletRequest request) {
            return (HttpServletRequest) request;
        }

        private HttpServletResponse asHttp(ServletResponse response) {
            return (HttpServletResponse) response;
        }

        private boolean postToAuthenticate(HttpServletRequest httpRequest, String resourcePath) {
            return Constant.AUTHENTICATE_URL.equalsIgnoreCase(resourcePath) && httpRequest.getMethod().equals("POST");
        }

        private void processUsernamePasswordAuthentication(HttpServletResponse httpResponse,String username, String password) throws IOException {
            Authentication resultOfAuthentication = tryToAuthenticateWithUsernameAndPassword(username, password);
            SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
            httpResponse.setStatus(HttpServletResponse.SC_OK);
            httpResponse.addHeader("Content-Type", "application/json");
            httpResponse.addHeader("X-Auth-Token", resultOfAuthentication.getDetails().toString());
        }

        private Authentication tryToAuthenticateWithUsernameAndPassword(String username,String password) {
            UsernamePasswordAuthenticationToken requestAuthentication = new UsernamePasswordAuthenticationToken(username, password);
            return tryToAuthenticate(requestAuthentication);
        }

        private void processTokenAuthentication(String token) {
            Authentication resultOfAuthentication = tryToAuthenticateWithToken(token);
            SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
        }

        private Authentication tryToAuthenticateWithToken(String token) {
            PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token, null);
            return tryToAuthenticate(requestAuthentication);
        }

        private Authentication tryToAuthenticate(Authentication requestAuthentication) {
            Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication);
            if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) {
                throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials");
            }
            logger.debug("User successfully authenticated");
            return responseAuthentication;
        }

Mein Controller ist 

@RestController
public class UserController {

    @Autowired
    UserService userService;

    /**
     * to pass user info to service
     */
    @RequestMapping(value = "api/v1/signup",method = RequestMethod.POST)
    public String saveUser(@RequestBody User user) {
        userService.saveUser(user);
        return "User registerted successfully";
    }
}

Ich bin total neu im Frühling, bitte hilf mir, wie es geht?

51
Prabjot Singh

Bei Verwendung von permitAll bedeutet dies jeden authentifizierten Benutzer. Sie haben jedoch den anonymen Zugriff deaktiviert, damit dieser nicht funktioniert. 

Sie möchten bestimmte URLs ignorieren, überschreiben Sie dabei die configure-Methode, die WebSecurity-Objekt und ignore das Muster verwendet.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/v1/signup");
}

Und entfernen Sie diese Zeile aus dem Teil HttpSecurity. Dadurch wird Spring Security angewiesen, diese URL zu ignorieren und keine Filter darauf anzuwenden.

96
M. Deinum

Ich habe einen besseren Weg:

http
    .authorizeRequests()
    .antMatchers("/api/v1/signup/**").permitAll()
    .anyRequest().authenticated()
9
javajoker
<http pattern="/resources/**" security="none"/>

Oder mit Java-Konfiguration:

web.ignoring().antMatchers("/resources/**");

Anstelle der alten:

 <intercept-url pattern="/resources/**" filters="none"/>

für exp. Deaktiviere die Sicherheit für eine Login-Seite:

  <intercept-url pattern="/login*" filters="none" />
7
Sagar Bhandari

Dies ist möglicherweise nicht die vollständige Antwort auf Ihre Frage. Wenn Sie jedoch nach einem Weg suchen, den CSRF-Schutz zu deaktivieren, können Sie Folgendes tun:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/web/admin/**").hasAnyRole(ADMIN.toString(), GUEST.toString())
                .anyRequest().permitAll()
                .and()
                .formLogin().loginPage("/web/login").permitAll()
                .and()
                .csrf().ignoringAntMatchers("/contact-email")
                .and()
                .logout().logoutUrl("/web/logout").logoutSuccessUrl("/web/").permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin").password("admin").roles(ADMIN.toString())
                .and()
                .withUser("guest").password("guest").roles(GUEST.toString());
    }

}

Ich habe die vollständige Konfiguration hinzugefügt, aber die Schlüsselzeile lautet: 

.csrf().ignoringAntMatchers("/contact-email")
4

Als @M.Deinum schrieb die Antwort bereits. 

Ich habe es mit api /api/v1/signup versucht. Es wird den Filter/benutzerdefinierten Filter umgehen, aber eine zusätzliche Anforderung, die vom Browser für /favicon.ico aufgerufen wird, füge ich dies auch in web.ignoring () hinzu und funktioniert für mich.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/v1/signup", "/favicon.ico");
}

Möglicherweise ist dies für die obige Frage nicht erforderlich.

0
eigenharsha