How can I define a #RequestMapping method to explicit allow anonymous (unauthorized) access?
The following does not work, always getting 401 Unauthorized:
#RequestMapping("/test")
#Secured(value={"ROLE_ANONYMOUS"})
public String test() {
return "OK";
}
In general the whole application is secured as follows, using spring-boot:
security.basic.enabled=true.
#Configuration
public class AuthConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
You can override configure(HttpSecurity httpSecurity) method and define your rules there:
#Configuration
public class AuthConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception
{
httpSecurity.authorizeRequests()
.antMatchers("/test")
.permitAll();
super.configure(http);
}
}
#Configuration
public class AuthConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception
{
httpSecurity.authorizeRequests().regexMatcher("^((?!test).)*$").permitAll();
}
}
I am not sure about a slash before test but just try this negative look-around method.
Related
I am trying to use the below class
#EnableWebSecurity
#Configuration
public class WebConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private JwtRequestFilter jwtRequestFilter;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers(
"/v2/api-docs",
"/swagger-resources/**",
"/swagger-ui.html",
"/webjars/**" ,
"/swagger.json").permitAll();
}
#Bean
public UserDetailsService userDetailsService() {
return super.userDetailsService();
}
}
to enable cors
When trying to write my Junit
#RunWith(JUnitPlatform.class)
public class WebConfigTest {
#InjectMocks
private WebConfig webConfig;
#Mock
private AuthenticationManagerBuilder auth = Mockito.mock(AuthenticationManagerBuilder.class);
#Mock
private HttpSecurity http;
#BeforeEach
public void setUp() throws Exception {
MockitoAnnotations.openMocks(this);
}
#Test
public void testConfigure() throws Exception {
System.out.println(http);
System.out.println(webConfig);
}
}
WebConfig and HttpSecurity are getting mocked, please suggest
I am trying to secure REST api in my Spring Boot application by oAuth2 standard. I created classes extending AuthorizationServerConfigurerAdapter, ResourceServerConfigurerAdapter and WebSecurityConfigurerAdapter and unfortunately it works only with login scenario. /oauth/token request returns access_token etc, but in every other case I get 401, Unauthorized, Bad credentials. I thought that wrong cliendId/secret was the case, but it would also affect login, right?
P.S Application is connected to MySql database.
I already ran out of ideas, so maybe you guys are able to help me.
WebSecurityConfig.java :
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsServiceImpl userDetailsService;
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
#Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(bCryptPasswordEncoder);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/oauth/token").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
AuthorizationServerConfig.java :
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("client-credentials", "password","refresh_token")
.authorities("ROLE_CLIENT", "ROLE_ANDROID_CLIENT")
.scopes("read", "write", "trust")
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(5000)
.secret("secret")
.refreshTokenValiditySeconds(50000);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
}
}
ResourceServerConfig.java :
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/api/**").authenticated();
}
}
MainApplication.java :
#SpringBootApplication
#ComponentScan({"com.user.app"})
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
#Autowired
public void authenticationManaget(AuthenticationManagerBuilder builder, UserRepository repository) throws Exception {
builder.userDetailsService(new UserDetailsServiceImpl());
}
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
Ok, somehow oAuth2 configuration was overwritten by base configuration in some places. Those places still weren't protected by oAuth, so that's why "Bad Credentials" error was occurring even after providing proper access token. Commenting configure() method inside WebSecurityConfig solved the problem.
I am trying to follow this tutorial on setting up OAuth authentication in my web application I have just started, I am fairly new to spring and have been scratching my head over as to why the OAuth2AuthorisationServerConfig class cannot pick up the bean.
#Configuration
public class ServerSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("JL").password("TEST").roles("USER");
}
#Override
#Bean //Here is the bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/login", "/register").permitAll()
.anyRequest().authenticated()
.and().formLogin().permitAll()
.and().logout().permitAll();
}
}
#Configuration
public class OAuth2AuthorisationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean") // here is the qualifier for bean
private AuthenticationManager authenticationManager;
....
}
The two classes are in the same package
On the OAuth2AuthorisationServerConfig class I had annotated it with #ComponentScan and this seemed to have solved the problem
I want to replace the default access denied page:
With my custom page and my approach was this:
#Configuration
#EnableWebSecurity
public class SecurityContextConfigurer extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().maximumSessions(1)
.sessionRegistry(sessionRegistry()).expiredUrl("/");
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/security/checkpoint/for/admin/**").hasRole("ADMIN")
.antMatchers("/rest/users/**").hasRole("ADMIN").anyRequest()
.authenticated().and().formLogin().loginPage("/")
.defaultSuccessUrl("/welcome").permitAll().and().logout()
.logoutUrl("/logout");
}
#Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
#Bean
public AuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
return daoAuthenticationProvider;
}
#Bean
public ProviderManager providerManager() {
List<AuthenticationProvider> arg0 = new CopyOnWriteArrayList<AuthenticationProvider>();
arg0.add(daoAuthenticationProvider());
return new ProviderManager(arg0);
}
#Bean(name = "myAuthenticationManagerBean")
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return providerManager();
}
#Bean
public ExceptionTranslationFilter exceptionTranslationFilter() {
ExceptionTranslationFilter exceptionTranslationFilter =
new ExceptionTranslationFilter(new CustomAuthenticationEntryPoint());
exceptionTranslationFilter.setAccessDeniedHandler(accessDeniedHandler());
return exceptionTranslationFilter;
}
#Bean
public AccessDeniedHandlerImpl accessDeniedHandler() {
AccessDeniedHandlerImpl accessDeniedHandlerImpl = new
AccessDeniedHandlerImpl();
accessDeniedHandlerImpl.setErrorPage("/page_403.jsp");
System.out.println("ACCESS DENIED IS CALLED......");
return accessDeniedHandlerImpl;
}
private class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint{
#Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authenticationException) throws IOException,
ServletException {
response.sendError(HttpServletResponse.SC_FORBIDDEN,
"Access denied.");
}
}
}
But with this config above I'm still not getting the job done and seeing the same
Are there more bean which must be injected for this purpose?
Disclaimer : this is not only solution, but a working one.
In this case my approach would be as simple as possible which is add this method in your SecurityContext
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().maximumSessions(1)
.sessionRegistry(sessionRegistry()).expiredUrl("/");
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/security/checkpoint/for/admin/**").hasRole("ADMIN")
.antMatchers("/rest/users/**").hasRole("ADMIN").anyRequest()
.authenticated().and().formLogin().loginPage("/")
.defaultSuccessUrl("/welcome").permitAll().and().logout()
.logoutUrl("/logout").and()
.exceptionHandling().accessDeniedPage("/page_403");//this is what you have to do here to get job done.
}
Reference: Custom 403 Page in Spring Security.
As #M. Deinum pointed out, you should tell Spring Security how to incorporate these beans. Anyway, there is a much simpler way for what you're trying to achieve:
#Configuration
#EnableWebSecurity
public class SecurityContextConfigurer extends WebSecurityConfigurerAdapter {
// Rest omitted
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// The usual stuff
.exceptionHandling()
.accessDeniedPage("/page_403.jsp")
.authenticationEntryPoint((request, response, authException) -> {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
});
}
}
I created a Spring Boot - Security project based on a example app, however the Rest Controller works fine, means, I can access the rest resource but the security does not seem to fire up at all, so when I added a breakpoint as stated below it does not break there. Not sure why.
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// #formatter:off
auth.inMemoryAuthentication() // breakpoint here
.withUser("roy")
.password("spring")
.roles("ADMIN");
// #formatter:on
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Here is the complete project hosted and editable with Codio: http://bit.ly/1uFI0t5
You have to tell the framework which are the urls that it have to secure.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**").access("hasRole('ROLE_USER')")
.and().formLogin();
}
}