WebTestClient Authenticated Request - spring-boot

I'm trying to test my reactive(WebFlux) controller. Authenticated user makes request and I create some resource and current user is its owner(I need to know, who made this request, so simple #WithMockUser doesn't work). I use JWT authentication.
And I can't write proper test for that. In case of simple Spring MVC, there is
mockMvc.perform(...).with(user("username").roles("USER"))..
But I can't find anything similar for WebFlux. I tried to mutate webTestClient like this:
webTestClient.mutateWith(mockUser(...))
webTestClient.mutateWith(mockAuthentication(...))
Unfortunately, it doesn't work.
Any help is appreciated! Thanks in advance.

Related

Is it a good idea to handle optional JWT Authentication in Filter?

I am new to Spring Boot and my current project is a REST API developed in Spring Webflux. The goal is to have an endpoint which has an optional JWT Token, allowing you ti create things anonymously or not. But all the starter guides to Spring Security are really complicated and use Spring MVC, as far as I can tell.
Now my idea was to create a HandlerFilterFunction looking like
class AuthenticationFilter : HandlerFilterFunction<ServerResponse, ServerResponse> {
override fun filter(request: ServerRequest, next: HandlerFunction<ServerResponse>): Mono<ServerResponse> {
val authHeader = request.headers().header("Authorization").firstOrNull()
// get user from database
request.attributes()["user"] = user
return next.handle(request)
}
}
and adding it to the router {...} bean.
Is this a good idea, or should I go another router? If so, can somebody point me towards a JWT tutorial for Spring Webflux.
The Spring Security docs point to a JWT-Based WebFlux Resource Server sample in the codebase.
It's not Kotlin-based, so I also posted a sample of my own just now; hopefully, it helps get you started.
As for your question, yes, you can create a filter of your own, though Spring Security ships with a BearerTokenAuthenticationFilter that already does what your filter would likely do. The first linked sample adds this filter manually while the second sample lets Spring Boot add it.

Where is the refreshToken endpoint implementation?

I am using springboot-security-jwt because have good recomendation, and it is running... But when I was testing refreshToken, where the implementation? How to use it?
Perhaps it is so obvious for a "Senior Developer Spring", but it is not for me, I not see it there. Where the /auth/token endpoint implementation?
There are some examples or documentation about it and how to (parameters) call it?
... Where the springboot-security-jwt /token endpoint implementation? to check it (or a kind of "health endpoint test")...
The primary configuration in the project springboot-security-jwt is in the WebSecurityConfig.java: (see https://github.com/svlada/springboot-security-jwt/blob/master/src/main/java/com/svlada/security/config/WebSecurityConfig.java).
In this class you will see a bean created of type AjaxLoginProcessingFilter configured with to intercept requests matching "/api/auth/login". This will process the login and generate the JWT tokens.
You can then follow to the next bean configured - JwtTokenAuthenticationProcessingFilter to see what it is intercepting and authenticating using the JWTToken provided on the api requests
refreshToken is a standard spring controller - see RefreshTokenEndpoint class (https://github.com/svlada/springboot-security-jwt/blob/master/src/main/java/com/svlada/security/endpoint/RefreshTokenEndpoint.java)
The author also provides a detailed explanation in the Blog.md under the etc folder - check it out! there are lots of useful links to get up to speed on using JWTs

How do I setup login service for Spring-social and spring-security over a REST API?

I want to have a JS application in on client-side (no jsps) that will communicate with back-end only with REST calls. I want also to enable users to be able to login with FB, Twitter accounts. In addition, I also want to enable users to register their own accounts. For this purpose I want to use Spring-security and spring-social on backend and Javascript SDK in front to get access_token from the FB, which will be then passed to backend.
The question is: how do I create a REST controller that would authenticate using spring-social and spring-security facilities?
I read through the examples in:
https://github.com/spring-projects/spring-social-samples
but couldn't really find how I could make use of ProviderSignInController or SpringSocialConfigurer for this purpose. I guess I cannot use the SocialAuthenticationFilter in my case since the "/auth/{providerid}" url is not what I'm looking for. However, I guess the ProviderSingInController seems to be of use here neither. Please correct me if I'm wrong. Ideally I would like to benefit from all capabilities of Spring Security framework.
I will appreciate any suggestions.
Best regards
EDIT
I would like to follow a flow like here: http://porterhead.blogspot.com/2013/01/writing-rest-services-in-java-part-4.html but using the Spring Social and Spring Security combined.
The front-end application is written in AngularJS
2nd EDIT
It turns out that you can simply make use of all the Spring Social modules benefits out of the box. The only thing a client has to do is call a GET on the auth/facebook or whatever link to fire entire 0auth dance which will eventually return the authentication result. Then you can control the flow easily (register account or return some relevant information to the client to let know registration is needed). So the SpringSocialConfigurer works well in this case (apart from the fact that it doesn't support scope setting yet, however, this can be changed manually, check my pull request # github.com/spring-projects/spring-social/pull/141)
3rd EDIT - 14.10.2014
As requested, I will share how I managed to make it work.
Given I have configured my security filter in the following way:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
public void configure(final HttpSecurity http) throws Exception {
http.formLogin()
...
.and().apply(getSpringSocialConfigurer());
}
private SpringSocialConfigurer getSpringSocialConfigurer() {
final SpringSocialConfigurer config = new SpringSocialConfigurer();
config.alwaysUsePostLoginUrl(true);
config.postLoginUrl("http://somehost.com:1000/myApp");
return config;
}
Once my application is set up, the only thing I need to call is http://somehost.com:1000/myApp/auth/facebook
with GET request.
"In addition, I also want to enable users to register their own
accounts"
If you say that you want to allow users to login with their own credentials (without FB/twiter), you need to let them also to create account, and to support forgot password, etc...
If that is the case, maybe this SO thread might be helpful. The auth-flows package also supports REST API.
Create Account, Forgot Password and Change Password

For validating session attribute, which is better in spring - Interceptor or Spring AOP?

In my application, after a user is logged in, every time he sends a request (get/post), before calling the method in controller, i want to verify the session attribute set in the request (i set a session attribute during his login). I see that this can be implemented through spring interceptors (OR) spring AOP. which one should i use?. I have a feeling interceptors are outdated. Or is there a way in spring security which does this for me?
So you want this intercept to happen only for all the controller methods ..? Does the controller have Base URL that its getting invoked for (post/get/delete)...? Is it more like you want to intercept the http request for a particualt URL ..? like this one
<intercept-url pattern="/styles/**" filters=" .." />
If your use case is boiled down to a particular URL pattern then you can write a custom filter extending GenericFilterBean and you can plug it to the filters attribute.So this will get called for every request matching url pattern and in your custom filter you can do whatever you wanted to do.
What if you try implementing a simple Filter? You can extend already existing Spring filter, or create your own by implementing javax.servlet.Filter
The spring security way seems the best way to me with access to specific roles also can be assigned. very good example given in http://www.mkyong.com/spring-security/spring-security-form-login-using-database/

Spring Security: setUserPrincipal manually

In a webapplication with Spring MVC and Spring Security.
Is there a way to set UserPrincipal manually?
I need to switch to another user by an admin part of my webapplication. In my controller, is it possible to setUserPrincipal in the request? To connect as if I were someone else.
Like that: request.setUserPrincipal().getName()
I've done things like this to automatically log people in after registering. It seems that it would do just what you are looking for:
Authentication authentication = new UsernamePasswordAuthenticationToken(
userService.loadUserByUsername(u.getUserName()), null,
AuthorityUtils.createAuthorityList("ROLE_USER"));
SecurityContextHolder.getContext().setAuthentication(authentication);
I am grabbing my user from a service. This has to implement the org.springframework.security.core.userdetails.UserDetails interface.
I think this should give you a good idea of what needs doing. I remember it took me a while to piece this together from the docs.

Resources