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?
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.
Ich habe einen besseren Weg:
http
.authorizeRequests()
.antMatchers("/api/v1/signup/**").permitAll()
.anyRequest().authenticated()
<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" />
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")
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.