How to provide security for the password using spring - spring

I am new to spring. My requirement is:
I need to get the user name and password in my component class. validate it with by invoking the webservices available at my client.
So I want to provide security to my password which can not be directly visible anywhere.
So how to implement this?
Please give suggestions

Spring Security can participate in many different authentication environments. While we recommend people use Spring Security for authentication and not integrate with existing Container Managed Authentication, it is nevertheless supported - as is integrating with your own proprietary authentication system.
What is authentication in Spring Security?
Let's consider a standard authentication scenario that everyone is familiar with.
A user is prompted to log in with a username and password.
The system (successfully) verifies that the password is correct for the username.
The context information for that user is obtained (their list of roles and so on).
A security context is established for the user
The user proceeds, potentially to perform some operation which is potentially protected by an access control mechanism which checks the required permissions for the operation against the current security context information.
The first three items constitute the authentication process so we'll take a look at how these take place within Spring Security.
The username and password are obtained and combined into an instance of UsernamePasswordAuthenticationToken (an instance of the Authentication interface, which we saw earlier).
The token is passed to an instance of AuthenticationManager for validation.
The AuthenticationManager returns a fully populated Authentication instance on successful authentication.
The security context is established by calling SecurityContextHolder.getContext().setAuthentication(...), passing in the returned authentication object.
This could help: http://www.viddler.com/v/c596114a

Related

Add additional inner user validation after successful OAuth2 Resource Server JWT check at Keycloak

There is a Spring boot app with endpoints protected with JWT. Token validation is performed by Spring boot OAuth2 Resource Server that checks tokens at Keycloak Authorization Server.
How can additional inner user validation be added to the app after it successfully passes authorization at Keycloak?
So I'd like to build some kind of a chain - if token passes validation at Auth Server then I check the username taken from JWT at local database.
Checking access-token claims against local database for access-control on a resource-server is an easy task inside authentication converters (http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(...) or http.oauth2ResourceServer().opaqueToken().authenticationConverter(...), but this is very inefficient: it is much better to have this DB access once when the token is created on authorization-server, rather than each time it is evaluated during resource-server authorization process (which happens for each request).
All the data required for access-control decisions should be included in the token already. If you need more than standard claims plus the default private claims from your authorization-server, then configure this authorization-server to add the data you need about the user when issuing access-tokens. For Keycloak, this is done with so called "OIDC protocol mappers". Those can issue DB requests, web-service calls and about anything. I have a sample of a mapper adding a private claim with a value from a web-service call in this project.
Once all the data you need is in the token, you just use it as normal in Spring security expressions of your resource-server. Here is a working sample taken from my set of tutorials:
#PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')")
In this expression, it is checked that the user either:
is greeting himself (username #PathVariable is equal to preferred_username claim in access-token)
has one of "nice" roles
has permission to greet on behalf of user with preferred_username equal to username #PathVariable (the route is /greet/{username} and this permissions delegation is taken from a private claim added by a mapper like the one in the sample linked above)

Why do we need Keycloak permissions/policies/scopes if we want to control access on the backend?

I'm still not able to understand the purpose of keycloak permissions/scopes/policies if we still validate user per resource based on the role of the user.
I use Spring Boot and all the documentations shows that role must be included in the configuration:
...
.antMatchers("/api/account").hasRole("account")
.anyRequest()
.authenticated();
We have configured the above policy in the keycloak but on the backend we again check the user role. Why do we need keycloak policy configuration?
In keycloak, we can create authorization scopes. How can I use that scope to protect my api based on this scopes?
I couldn't find a way to add authorization scopes into JWT token but keycloak provides UMA endpoints to fetch scopes, but would it be correct way to implement?
By default, spring-security is based on user "granted authorities" (in spring world, roles are just authorities with ROLE_ prefix). Spring-boot default configuration for JWT turns scopes into authorities.
But you might use SpEL in #PreAuthorize() or #PostAuthrize() and write security rules involving more than just user authorities. See for instance this expression taken from here:
#PreAuthorize("is(#grantingUsername) or hasAuthority('USERS_ADMIN') or onBehalfOf(#grantingUsername).can('PROXIES_EDIT')")
It checks user either:
is "granting user": username retrieved from JWT token equals grantingUsername path variable
is granted with USER_ADMIN authority
was granted with PROXIES_EDIT permission by "granting user"
You can write about anything with security SpEL, based on security-context (Authentication instance created from access-token JWT) and annotated method parameters or returned value.
OpenID standard only defines how resource-owners identity must be presented. It contains nothing specific about permissions.
As so, each authorization-server is using its own private-claims for permissions (roles, resource-access, etc.).
By default, Keycloak exposes realm roles in realm_access.roles claim. You can also add user roles specific to a client with client roles mapper (in admin console: clients -> some-client -> mappers and then click Add Builtin button). This will put client roles in a claim like resource_access.some-client.roles. You can also write your own mappers to feed any claim with what you need (I wrote such a mapper here). But all this is very Keycloak specific.
If you already defined user roles (or whatever your security rules are based on) in Keycloak, you should find it in JWT access-tokens (open it in a tool like https://jwt.io to check). If so, all you need to do is replace Spring default JwtGrantedAuthoritiesConverter (which converts scopes to authorities) with a converter extracting authorities from Keycloak specific claims for roles.
You could also use libs I wrote for spring-boot OpenID resource-servers.
Please refer to tutorials in this repo to get started. resource-server_with_oauthentication can provide you with a resource-server with role based access control in 5 minutes (including security rules unit-tests).
If you want to do something else than role-based access control, you'll have to override more #Beans and spring-security components. You could start with this advanced tutorials or the api module of the complete application from which I took security expression above.

Spring Security custom validation without using user password involved

I was wondering if in Spring Security is possible to lock all endpoints of a rest api, and to do a login by doing a custom validation without using the username and password at all.
It is like create a custom validation method that receives a token and not user/pass. The method will then validate the token with third party that has already validated the caller.
This sounds familiar to OAuth2 only that the backend API needs to be secure by spring, and at the same time it is not the OAuth2 client:
We are building a login feature.
We have a client (mobile app), backend (REST like endpoints Spring MVC), and an AuthProvider for OAuth2/OpenIdConnect flows.
The OAuth/OpenIDConnect flow happens only between the mobile and OpenIDProvider. (an initial call happens from mobile to backend to provide some details for oauth flows)
Once the authorization succeeded, the mobile app receives an auth_code, and only then the backend is called from the app to "Login" which means validate the auth_code, exchange for access_token, and create user session. (we need to have a session).
As you see backend kind of "login" in the sense that needs to receive the auth_code only, and validate it with the AuthProvider before creating a session.
Thank you very much!
Any comments, or references are very appreciated.
Spring Security determines if a user is authenticated by looking at the SecurityContext in the SecurityContextHolder. This means you can authenticate the user however you like using the following:
boolean userIsAuthenticated = ...
if(userIsAuthenticated) {
Authentication request = new UsernamePasswordAuthenticationToken(name, password);
Authentication result = ...
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(result);
SecurityContextHolder.setContext(context);
}
Spring Security is a very flexible framework that publishes a variety of interfaces that allow the user to customize the behavior as need be.
I'd recommend the following resources to learn how to go about this:
Architecture Deep Dive in Spring Security
Spring Security Custom Authentication Provider
Spring Security Custom AccessDecisionVoters
Spring Security Reference Documentation

Spring security workflow

I'm new to Spring Security, and I can't grasp the basic workflow of it. I read again and again the official documentation but I feel more confused. I can't figure out what are exactly :
authentication manager/provider
authentication object
user detail
user details service
It seems that authentication object is built thanks to user detail but the latter need the former to be built (that's what I understood from the doc).
Does anyone have a simple explanation on how all of these things are used ?
Authentication manager allows multiple authentication providers (eg an in memory db and a normal db?). Authentication provider looks up a user details implementation, via whichever user details service has been specified. The authentication object is then created from that.
User service and user details implementation are completely independent of spring security, you do not need spring security to use them.
[Ref docs]

User Authentication with spring 3.0

I tried searching in Google, but I could not find any good examples where a username and password are checked with a database for authentication purposes.
In further simple words, how can I create a simple login form using Spring and Hibernate and NOT SPRING SECURITY where the credentials are checked with the database.
Please help me creating a simple login form with just Spring 3.0 and no Spring Security 3.0. Thanks.
Simplest way to do a login form post to a Spring Controller which take username and password as parameter.
In the controller you do what ever you want to authenticate the username and password. Best is to delegate to some service layer which takes care of it.
If successfully authenticated then what you want to do? May be redirect to say home page.
Now the home page rendering should know that the user is already authenticated. This is where spring security helps.
But you can also achieve by writing a Servlet Filter where you check if user is already authenticated by checking the http session. Of course after successful login you need to store that in the session then only it will be available to the filter.
There are many other ways to achieve the same which depends upon your requirement as in what kind of security control is required.
Your solution has two parts, one of which involves Spring and another that is your code:
// DAO returns null if no such username appears in the table.
String password = userDao.findPassword(username);
boolean isValidUser = (!password.equals(null));
// Write the code to implement behavior for valid and invalid users.
If you can do a database SELECT for a password, you can do Spring authentication without Spring Security.
You may need to put that logic in an aspect that's woven in before method calls.
You may want to cache that result in session and invalidate it if a timeout is exceeded.

Resources