Set logged in user without spring security - spring

I'm not a big fan of Spring Security, I think it's too overrated. So i'm trying to use alternatives to secure my rest API, and one of them which I like is Spring sandwich which based on interceptors.
The only issue i have though is that I want smth similar to SecurityContextHolder.getContext().getAuthentication().getPrincipal();
so I don't have to pass the user every time but more of a global object.
Anybody has any idea how to do that?
ps: i'm using spring boot

Although I highly suggest reconsidering Spring Security, you can also use HttpSession as an alternative.
When an user logs in, you can store your 'User' object in his session like so:
#RequestMapping("/login")
public String login(HttpSession session, #RequestParam String username, #RequestParam String password) {
// check if user has right credentials ...
session.setAttribute("USER", user);
return "You have logged in successfully"; // you can also redirect instead, do as you wish
}
and then you can access the User object like so:
User user = (User)session.getAttribute("user");
you can also get the session from HttpServletRequest (request.getSession())
Alternatively, if you can't pass the object HttpSession to your controller for some reason, you can also autowire the session like so:
#Autowired
private HttpSession session;
See Spring Session for more details

Related

How do I extract the Oauth2 access token in a Spring application using code grant flow?

I have followed this guide.
I have a simple Oauth2 webapp using code grant authorization flow. I have a #GetMapping endpoint (as per the tutorial) that returns user information retrieved from a service provider I'm using. Since this correctly returns my information to the webapp, I can tell the code grant flow has worked. Code for working endpoint:
#GetMapping("/user")
public Map<String, Object> user(#AuthenticationPrincipal OAuth2User principal) {
return principal.getAttributes();
}
Now I want to create a new #GetMapping where I use the access token to query the API of the service provider that just authorized us.
The problem is that the example above somehow magically makes the request for me based solely on configuration and only returns user info. Now I want to get the access token for this session that Spring stores somewhere to access the API however I like "manually".
How can I extract the access token in my new #GetMapping?
I have been searching a lot, but I am new to both Oauth2 and Spring, and there is so much spring classes and tutorials that I "can't see the forest because of all the trees".
I appriciate any help.
Cheers.
I solved it.
Add the following:
#Autowired
private OAuth2AuthorizedClientService authorizedClientService;
private String getSessionBearerToken() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
OAuth2AuthorizedClient client =
authorizedClientService.loadAuthorizedClient(
oauthToken.getAuthorizedClientRegistrationId(),
oauthToken.getName());
return client.getAccessToken().getTokenValue();
}
This method will get you the access token when you call it.

How to get google logged in user's details in spring boot app

I am implementing google login using oauth2 in spring boot app. Now I am stuck, as I don't know how to get user details. Using Authentication or Principal object I can only get username(which is some random number) with method princial.getname() method and there are no other relevant methods to get the details.
Since the OAuth2 framework is designed to be generic, you will not find methods for anything other than the principal name.
Instead, the OAuth2User class has a getAttributes method which returns the attributes from the user info uri of the specific provider as a map.
This is how you get the user object of the current request:
#GetMapping("/user/me")
public Map<String, Object> userDetails(#AuthenticationPrincipal OAuth2User user) {
return user.getAttributes();
}
Try this and you will see which exact attributes google supports.

Is there any advantage using UserDetailsService of Spring Security, when setting membership with JWT?

I'm applying JWT to authenticate the requests. Parsing and Validating works in my Spring Cloud Gateway.
I made a custom filter on SecurityWebFilterChain, which parse and validate the JWT in request header.
I will add this custom filter to ServerHttpSecurity using ServerHttpSecurity.addFilterBefore(myCustomJwtRequestFilter, UsernamePasswordAuthenticationFilter.class).
I want to use
SecurityContextHolder.getContext().setAuthentication(authentication) of Spring Security to authenticate the request.
I found that most of examples of it use UserDetails to make Authentication class.
Most of examples I found use UsernamePasswordAuthenticationToken, and I found that it requires UserDetails. To build UserDetails, it essentially requires username, password, roles.
But in my case, I do not want to validate my jwt with User DB every time I got requests. Also, I do not need the password of user since I will not validate it once I generated Token. I want to use only Username and Roles in JWT payload itself.
In summary, I want to make Authentication class only with username and roles and set it authenticated if parsed jwt is validated with my custom method.
It works well with custom userDetails:
UserDetails userDetails = User.builder().username(String.valueOf(parsedInfo.get("username")))
.authorities(parsedInfo.get("roles")).password("dummypassword").build();
But I have to set Dummy password into it, which I do not need.
I think my solution is not properly applying spring security.
But if I won't use UserDetails, is there benefit to use spring security?
Is there any better solution for my case?
If you just need to validate the JWT token then you can use Spring AOP for that.
#Aspect
#Component
public class JwtAspect {
#Before("execution(* com.yourpackageName.* (..))")
public void checkJwtToken(JoinPoint joinPoint) {
String jwtTOken = request.getToken();
if (null == jwtToken) {
throw new Exception("Token Not Found. ");
}
parseToken(jwtToken);
joinPoint.proceed();
}
}
If you get the token, parse it and also check the expiry. If above everything works fine, you can proceed your JoinPoint.

Spring UserDetails and my User implementation in session

I'm developing my Spring application with the support of Security Model.
I configured everything and it seems to work fine, but I have a conceptual question.
In my controller I can retrieve the User Details generated by Spring like this:
UserDetails userDetails = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Now, should I put this user in the Http session or it's useless?
And also, should I retrieve my User implementation on the basis of the UserDetails object and put it in the session?
What is the right way of thinking with security? I would need my user implementation to retrieve some information but I don't know to keep both around.
http://docs.spring.io/spring-security/site/docs/3.0.x/reference/technical-overview.html#d4e731 in this docks 5.3.1 you can see example.
Something like this:
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);

Spring Security user account registration, creation and management

I've been looking into using Spring Security for the authentication/authorization of my web application (this will be JDBC based).
However, a core component seems to be left out from my perspective. How do I register/create new users? Is there an out of the box API for that?
Do i need to write user registration and management from scratch?
Things i need to do include:
- Registering a new user
- Resetting passwords
- Emailing a user to activate their account
- Emailing a user to reset their account.
Thank you in advance.
I use Spring Security on my project. The framework does not have an API for user creation or registration as you asked. For Spring Security to be generic and usable across multiple frameworks, it can only take you so far before you have to write custom code. You can't really get a more specific answer about a framework or tool to use because at this point you will just use the frameworks you are already using anyway.
If you've set it up to use users and roles in your database, from your data access layer you would create a record in the user table or update a password (preferably stored as a hash) in that record. And as Aravind said, Spring does provide email support.
If you really want to see one way to do it: I'm using Spring MVC, JSP, and Hibernate. I use Spring's form tags in a JSP to bind a new user form to a Person object, and my controller method passes that Person object to my Dao to persist it.
The controller method signature looks like this...
#RequestMapping(value = "/newUser", method = RequestMethod.POST)
public ModelAndView createNewUser(final #Valid #ModelAttribute Person user,
final BindingResult result,
final SessionStatus status,
final #RequestParam(value = "unencodedPassword", required = true) String password) {
...
user.getRoles().add(new Role(user, Role.APPLICATION_ROLE.ROLE_USER));
userDao.createNewUser(user);
...
}
and my PersonDao would use Hibernate to persist the user like so
#Transactional
public void createNewUser(Person user)
{
Session session = sessionFactory.getCurrentSession();
session.save(user);
session.flush();
}
Have a look at my answer here.
"I have implemented a JAVA project for this use case. It is open
source, based on Spring-Security. A release version is on
Maven-Central, so you do not need to compile it, but instead you can
fetch it as maven-dependency to your project!"
<dependency>
<groupId>com.ohadr</groupId>
<artifactId>authentication-flows</artifactId>
<version>1.5.0-RELEASE</version>
</dependency>
As far as I know, Spring Security does not have built in support for new user creation and registration. You will have to manage this yourself. However it does have emailing support. Check here for more on this.

Resources