#EnableOAuth2Sso AND #EnableResourceServer in same app - spring

I'd like have a set of services that can be used with "Client Credential" (for machine to machine) and with OAuth2 Single Sign On for the regular webapp (which is served by the same application).
I tried setting both #EnableOAuth2Sso and #EnableResourceServer; I expected to have the app "try" the token based and then fall back to SSO redirect in case it doesn't find any and the user does not have a session.
Each config works fine on its own (with a:
#Bean
public RemoteTokenServices ...
for #EnableResourceServer to configure the "CheckTokenEndpointUrl").
But as soon as I try with both I get:
APPLICATION FAILED TO START
Description:
Method springSecurityFilterChain in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration required a single bean, but 2 were found:
- userInfoTokenServices: defined by method 'userInfoTokenServices' in class path resource [org/springframework/boot/autoconfigure/security/oauth2/resource/ResourceServerTokenServicesConfiguration$RemoteTokenServicesConfiguration$UserInfoTokenServicesConfiguration.class]
- remoteTokenServices: defined by method 'remoteTokenServices' in class path resource [my/CustomWebSecurityConfigurerAdapter.class]

In your spring boot application class use the #EnableOAuth2Sso annotation and in the configuration class use #EnableResourceServer annotation and in this class define the endpoints to be used with access tokens.
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/user") //end point that needs access token in header
.antMatcher("/info") //end point that needs access token in header
.authorizeRequests().anyRequest().authenticated();
}
}
For more information refer the link

Related

An unwanted default login interface appears

I started a Springboot application looking to create a login/registration Webapp .
I only set up Thymeleaf and Bootstrap for the HTML template , and set up the service, the controller and the repository.
This is the first time this login interface shows and whenever I change the URL it goes back to localhost:8080/login
I made sure that the port is set on the current project, and that there is no request set for /login
It looks like there is a backend set up for it and I do not undrestand from where it is ...
This is from Springboot security auto configuration , I had to disable it manually adding a configurating class :
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity security) throws Exception
{
//security.httpBasic().disable(); // Did work only for GET
security.csrf().disable().authorizeRequests().anyRequest().permitAll(); // Works for GET, POST, PUT, DELETE
}
}

Reason for #EnableWebSecurity in the configuration class

I just read answer from the another question What is the use of #EnableWebSecurity in Spring?, but i couldn't understand why we need to add #EnableWebSecurity annotation at all.
Even I remove the #EnableWebSecurity from the configuration, my application still works.
Let's assume that we are going to implement either JWT based (rest api) or simply login based mvc application. For the following configuration what i am missing?
#Component
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
public UserDetailsService userDetailsService() {
return new MyCustomUserDetailsService();
}
#Bean
public PasswsordEncoder passwsordEncoder() {
return new BrcyptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// for the jwt authentication add jwt filter etc ..
// for the login based, override default login page, error page etc..
}
}
If you are not using spring-boot but just a pure spring project , you definitely need to add #EnableWebSecurity in order to enable spring-security.
But if you are using spring-boot 2.0 +, you do not need to add it by yourself because the spring-boot auto configuration will automatically do it for you if you forget to do so. Under the cover , it is done by the WebSecurityEnablerConfiguration which its javadoc also states this behaviour as follows:
If there is a bean of type WebSecurityConfigurerAdapter, this adds the
#EnableWebSecurity annotation. This will
make sure that the annotation is present with default security
auto-configuration and also if the user adds custom security and
forgets to add the annotation.

How to designate public endpoints using custom annotation in spring rest controllers?

We are using OAuth2 for securing our REST endpoints. Nearly all of our endpoints require authentication. We have couple of public endpoints. We configure spring security using #EnableWebSecurity. All the public endpoints are explicitly listed in the configuration (see "publicpath_x" in the example below). Instead of explicitly adding each new public enpodint in the configuration, it would be much easier to have a custom annotation, e.g. #PublicAccess which will designate each public endpoint. Is it possible to configure that endpoints annotated with this annotation will be considered as public, i.e. no authentication will be required? We don't want to designate public endpoints in path (e.g. all public endpoints path will start/end with "/public").
Security configuration:
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatchers("publicpath1", "publicpath2").permitAll() //...
}
}
Example public REST controller with custom annotation:
#RestController
public class PublicController1 {
#PublicAccess //our custom annotation
#RequestMapping(value = "publicpath1", method = RequestMethod.GET)
public void publicEndpoint1() {
//...
}
}
I was trying the following classes with no success.
javax.servlet.Filter
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
You can use the #PreAuthorize Annotations as method security
Detail see here

Spring OAuth Filter Chain & Java Config

I'm trying to add in spring-security-oauth to an existing app with spring-security. I'm using Java config.
I have an existing amended filter chain in place (with some custom filters added in) but requests to '/oauth/token' aren't using it, but are using the 'default' filter chain. How can i get access to the filter chain that's securing the oauth endpoints so that i can use the custom filters there also or can I wire in the OAuth endpoint(s) into the existing setup?
there is indeed a slightly smoother way using the interface AuthorizationServerConfigurer.
You can stick to the annotation #EnableAuthorizationServer and implement above interface in your configuration file. This will enable you to alter the oauth2-filter-chain by doing something like this:
#Configuration
#EnableWebSecurity
#EnableAuthorizationServer
public class SecurityConfig extends WebSecurityConfigurerAdapter
implements AuthorizationServerConfigurer
// some configuration ...
public void configure(AuthorizationServerSecurityConfigurer oauthSecurity) throws Exception {
oauthSecurity.addTokenEndpointAuthenticationFilter(new YourFilter());
}
// more configuration ...
}
In contrast to the addFilterXYX-methods of HttpSecurity you have no fine-grained influence here where the filter will be positioned in the filter chain. Any filter added by addTokenEndpointAuthenticationFilter will be inserted before the BasicAuthenticationFilter.
If you need to control the position of you filter in a more detailed way you could create a bean extending AuthorizationServerConfigurerAdapter instead of using the annotation #EnableAuthorizationServer. I did not try that but I guess you could then extend AuthorizationServerSecurityConfigurationlike systemfreund suggested without having to specify #Order(-1) because only your custom configuration gets imported. Probably you would also have to #Import AuthorizationServerEndpointsConfigurationlike it is done in the convenience annotation #EnableAuthorizationServer.
It's probably not the best way to do it, but I did not manage to find a better approach. The idea is to provide a custom AuthorizationServerSecurityConfiguration instance and override the default instance which is #Imported via #EnableAuthorizationServer. We just need to make sure to add an #Order annotation with higher precendence than the default configuration:
#EnableAuthorizationServer
#Import(CustomSecurityConfig.class)
public class Application {
}
#Configuration
#Order(-1)
public class CustomSecurityConfig extends AuthorizationServerSecurityConfiguration {
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http); // do the default configuration first
http
.addFilterBefore(new MyFilter(), ...);
}
}

Add interceptor to spring boot mongodb rest example

I am trying to add an interceptor to a simple Spring-boot-mongodb-rest app, as can be seen here : http://spring.io/guides/gs/accessing-mongodb-data-rest/, in order to perform certain actions after the default rest handler is invoked. Here is my MongoRepository, whose CRUD operation is called upon a POST request to the server:
#RepositoryRestResource(collectionResourceRel = "reminder", path = "reminder")
public interface ReminderRepository extends MongoRepository<Reminder, String> {
List<Reminder> findBySendee(#Param("sendee") String sendee);
}
I am trying to register an interceptor for all HTTP requests by extending the WebMvcConfigurerAdapter class like this:
#Configuration
#ComponentScan
public class RemindxWebConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new RemindxInterceptor());
}
}
As mentioned in the spring boot docs, I have not added the #EnableWebMvc annotation to this. While running the application, the addInterceptors function does get called and adds the interceptor. However, the given interceptor is not called after the POST handler is invoked. I am unable to figure out a way to have spring use this RemindxWebConfig for all MongoRepository http requests. Any inputs are appreciated.

Resources