问题
I'm doing a little application that requires to login first. But for some 3rd party tool, I want to provide an API that doesn't require login. The login itself works fine, the API itself works, but I can't figure out how to tell Spring Security, that the API can be accessed without the need of authentication. I checked several topics here and on other websites and tried different versions, but none worked. Everytime I try to access the API, I get forwarded to the login form and have to login first.
My Code Looks like this so far, inside my Spring Security config:
/**
* configuration of spring security, defining access to the website
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/rest/open**").permitAll()
.antMatchers("/login**").permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.defaultSuccessUrl("/dashboard")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/j_spring_security_logout")
.logoutSuccessUrl("/login?logout")
.and()
.csrf();
}
And my controller:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PredictionOpenRestController {
@RequestMapping("/rest/open/prediction")
public String getPrediction() {
return "First Try!";
}
}
Somehow I have to feeling to miss something.
回答1:
See Spring Security Reference:
Our examples have only required users to be authenticated and have done so for every URL in our application. We can specify custom requirements for our URLs by adding multiple children to our
http.authorizeRequests()method. For example:protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/resources/**", "/signup", "/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") .anyRequest().authenticated() .and() // ... .formLogin(); }1 There are multiple children to the
http.authorizeRequests()method each matcher is considered in the order they were declared.2 We specified multiple URL patterns that any user can access. Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about".
3 Any URL that starts with "/admin/" will be resticted to users who have the role "ROLE_ADMIN". You will notice that since we are invoking the hasRole method we do not need to specify the "ROLE_" prefix.
4 Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA". You will notice that since we are using the hasRole expression we do not need to specify the "ROLE_" prefix.
5 Any URL that has not already been matched on only requires that the user be authenticated
Your second use of .authorizeRequests() overrides the first one.
Also see AntPathMatcher:
The mapping matches URLs using the following rules:
?matches one character
*matches zero or more characters
**matches zero or more directories in a pathExamples
com/t?st.jsp— matchescom/test.jspbut alsocom/tast.jsporcom/txst.jsp
com/*.jsp— matches all.jspfiles in thecomdirectory
com/**/test.jsp— matches alltest.jspfiles underneath thecompath
org/springframework/**/*.jsp— matches all.jspfiles underneath theorg/springframeworkpath
org/**/servlet/bla.jsp— matchesorg/springframework/servlet/bla.jspbut alsoorg/springframework/testing/servlet/bla.jspandorg/servlet/bla.jsp
Your modified code:
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/rest/open/**").permitAll()
.antMatchers("/login/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.defaultSuccessUrl("/dashboard")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/j_spring_security_logout")
.logoutSuccessUrl("/login?logout")
.and()
.csrf();
}
来源:https://stackoverflow.com/questions/39052457/spring-security-secured-and-none-secured-access