Adding custom user attribute in keycloak using spring boot app - spring

We can add users in keycloak from spring boot application using org.keycloak.representations.idm.UserRepresentation. but if we want to add a custom user attribute in keycloak using UserRepresentation then UserRepresentation does not allow us to add custom attribute.

Keycloak does allow you to add custom attributes to the user with the help of org.keycloak.representations.idm.UserRepresentation.
public void addCustomAttributesToUser(Map<String, List<String>> customAttributes, String userId) {
UserResource userResource = realmResource.users().get(userId);
UserRepresentation userRepresentation = userResource.toRepresentation();
userRepresentation.setAttributes(customAttributes);
userResource.update(userRepresentation);
}

Related

Roles and Permission at method level Spring boot

I need to have authorization at the method level so that the users with proper permissions only can access it. The method will contain a token as a parameter. I need to make an API call passing the token and get the user email id. Once I have the email id, I need to fetch the user's roles & permissions from the database. Then I invoke the method if the user have appropriate roles else return a 403 error.
Is there a way to get this done in spring boot? I will have multiple methods behind authorization and would like to have some kind of annotation at method level.
Thanks.
#PreAuthorize annotation is what you want
Please read the following link for spring method level authorization
baeldung method authorization
you will also need to undestand SPEL(Spring Expression Language) as this is what the PreAuthorize method gets as parameter , link can be found here
please note that spring uses the SecurityContext to get the user data(Role etc..), meaning that the user already passed the login(authentication) stage and has SecurityContext loaded for said user
Example:
//other annotations
#PreAuthorize("hasRole('ROLE_VIEWER')") // hasRole('ROLE_VIEWER') -> this is SPEL
public ResponseEntity<String> methodName() {
//method
}
You can use #PreAuthorize with more flex as:-
#PreAuthorize("#securityService.hasPermission({'PERMISSION_1'})")
and service:-
#Component("securityService")
public class SecurityService {
public boolean hasPermission(PermissionEnum... permissions) {
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication()
.getAuthorities();
for (PermissionEnum permission : permissions) {
if (authorities.contains(new SimpleGrantedAuthority(permission.toString))) {
return true;
}
}
return false;
}
}
You can make it as you want.
For more
https://dreamix.eu/blog/java/implementing-custom-authorization-function-for-springs-pre-and-post-annotations
https://try2explore.com/questions/10125443

Spring security access roles inside a method

In Spring security is it possible to get roles and properties the user might have associated with their token inside a method?
#PreAuthorize("hasAuthority(T(ROLES.Admin)")
#Timed
public ResponseEntity<base> save(#RequestBody body) throws URISyntaxException {
// here i want to get all the data associated whit this user ie. jwt token
// roles etc .. as i need to pass this on
}
I have seen you can get the principal
Yes,you can get it through Principal.like this:
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
user.getAuthorities();

How to retrive logged in user data in spring mvc and hibernate

I need to get current loggedin user's details along entertain session.Is there any poissible to do it in Spring and hibernate
I am new to spring and hibernate...Help me guys.
There are serveral ways in which you can accomplish this. In a controller you can inject a Pricipal as a parameter.
#RequestMapping()
public void getPricipal(Principal principal) {
Customer c = (Customer) pricipal;
}
You should also be able to inject the UserDetails directly as well. Spring will resolve it for you. Your Customer class must implement UserDetails
#RequestMapping()
public void getPricipal(Customer customer) {
}
As for having all details, you should be able to access the firstname, lastname etc, if you've implemented your own UserDetailsService where you return your custom UserDetails (Customer).

Grails 2.2.3 + Spring security core + Multi-tenant Single DB plugin

I am new to grails and I am trying to implement spring security core and Multi-tenant single db plugin.
I have implemented the spring security core first and implemented custom AuthenticationProvider and Authentication.
Then I have installed the multi-tenant single db plugin and ran the 'mt-spring-security' script that automatically created custom tenantResolver and tenantRepository. I have hard-coded the tenantId in tenantResolver for testing purpose.
I have added the #MultiTenant annotation in the domain classes.
#MultiTenant
class ClientUser implements Serializable {
long idclient_user
Userprofile user
Client client
int tenantId
...
}
In the AuthenticationProvider, the ClientUser data is not filtered for the current tenant. It is bringing the data the all the tenant.
class ClientAuthenticationProvider implements AuthenticationProvider {
Authentication authenticate(Authentication auth) throws AuthenticationException {
ClientAuthentication authentication = auth
String password = authentication.credentials
String username = authentication.name
String clientName = authentication.clientName
...
Userprofile.withTransaction { status ->
def user = Userprofile.findWhere(username: username)
def client = Client.findWhere(clientname: clientName)
def clientUser = ClientUser.findWhere(client: client, user: user) <-- NOT FILTERED FOR THE CURRENT TENANT. I HARD-CODED INVALID TENANTID IN THE TENANTRESOLVER AND EXPECTING IT TO FAIL BUT IT STILL FINDS THE USER.
if (!clientUser) {
throw new UsernameNotFoundException('User not found', username)
}
...
}
...
result
}
I am not sure how the multi-tenant and spring security works together. I am having a hard time understanding the Architecture/design.
If anyone could provided me with a sample implementation or point me in the right direction, it will be really helpful.
Thanks,
dinesh
The problem was that the multitenant filter was registered before the spring security filter so the tenantResolver was not called until after the Spring security authentication. I fixed this problem by setting the resolveTenantBeforeLogin to true in the config.groovy
In config.groovy, add this line
multiTenant.resolveTenantBeforeLogin=true
After i added this line, the tenantResolver is called first and then the authentication.

Get User details from Session in Spring Security

I am new to Spring MVC and Spring Security. I have performed log-in and registration functionality using Spring security and MVC. I am not able to find any way for session management .
I want to access some user details on all the pages like (email, name,id,role etc).
I want to save these to session object so I can get these on any of the page.
I get the following way for session in spring
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
auth.getPrincipal();
But from the object returned by this I can get only username and password details.
But I need to access more details of that user.
Is there any way to do this by saving it to session and the get on the jsp page?
or is there any OOTB way in spring to get this done?
Please help me to get solution for this.
Thanks in advance.
I want to get my model class object to be returned from SecurityContextHolder.getContext().getAuthentication().getDetails(); For this what I need to configure.
Regards,
Pranav
You need to make your model class implement the UserDetails interface
class MyUserModel implements UserDetails {
//All fields and setter/getters
//All interface methods implementation
}
Then in your spring controller you can do this:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
Object myUser = (auth != null) ? auth.getPrincipal() : null;
if (myUser instanceof MyUserModel) {
MyUserModel user = (MyUserModel) myUser;
//get details from model object
}
You can use this to get the UserDetails (or any implementation with your custom details).
UserDetails userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails();
If there are not available, you can load the user details from the UserDetailsService.
In both cases, I think you have to save them yourself in a session scope bean.

Resources