I have to design a application for an organization where Authentication need to be happen Using SSO with Azure Directory using spring boot.
All the employee Information is stored in the AD. My custom application will have it's own users and their roles which are saved in the Database. Not every Employee in the organization will have access to this application. Admin will add user and their roles in Database(Mysql).
I am able to figure it out to do SSO with AD by adding relevant details in properties-file and configuring WebSecurify Config class
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
@Autowired
private AADAuthenticationFilter aadAuthFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers(HttpMethod.OPTIONS,
"/**").permitAll().anyRequest().authenticated()
.and()
.oauth2Login()
.userInfoEndpoint()
.oidcUserService(oidcUserService);
http
.addFilterBefore(aadAuthFilter, UsernamePasswordAuthenticationFilter.class);
http
.headers()
.frameOptions().sameOrigin()
.cacheControl();
http
.csrf().disable()
.authorizeRequests().antMatchers(HttpMethod.OPTIONS,
"/**").permitAll().anyRequest().authenticated()
}
}
Once the user is validated, In response i will get JWT token, Which i will use for all my further API requests. But the Problem is, Here i am allowing all the Employees to access the application since he is authenticated using AD. But, Once User is Authenticated i want to check whether user is available in the database or not, If he is not available, i need to send invalid user, if he is valid user to my application, i need to fetch roles and send it to front end as a Valid response.
I also want to do service level authorization for the user, I have used @PreAuthorize Annotation for most of my services. @PreAuthorize("hasRole('ROLE_VIEWER') or hasRole('ROLE_EDITOR')")
Edit 1
public class UserDetailsServiceImpl extends OidcUserService implements
CustomUserDetailsService {
@Override
public OidcUser loadUser(OidcUserRequest userRequest) throws
OAuth2AuthenticationException {
OidcUser oidcUser;
String mail=userRequest.getClientRegistration().getRegistrationId();
Set<GrantedAuthority> grantedAuthorities = getAuthorities(mail);
oidcUser = new DefaultOidcUser(grantedAuthorities,
userRequest.getIdToken());
return oidcUser;
}
private Set<GrantedAuthority> getAuthorities(String email) {
List<RoleIdDetails>
roleIdDetails=usersRepository.getRoleIdDeatils(email);
final Set<GrantedAuthority> authorities =
roleIdDetails.stream().map(role -> new SimpleGrantedAuthority("ROLE_" +
role.getRoleName().toString().toUpperCase())).collect(Collectors.toSet());
return authorities;
}
}
I have updated With My Own Custom OidcUserService, But Still I'm not able to set the roles.
oidcUserService
in methodpublic OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException
,oidcUser
implementsDefaultOAuth2User
class. callgetName
method to get the username and then, check user in DB in loadUser method itself, Ref: github.com/spring-projects/spring-security/blob/master/oauth2/… – user9065831