![](/img/trans.png)
[英]Spring Boot + Google OAuth2: how to define user details service?
[英]How to correctly set role for User in oauth2 app spring boot
在我的應用程序中實施 oauth2 后,我正在努力解決 spring 安全問題。 這是我的第一次體驗,但很高興聽到好的或憤怒的評論。 這就是改進的方法。
問題:在我的應用程序登錄期間,我看到我從 DefaultOidcUser class 的 google oidcuser object 檢索。 此 object 具有 4 項authorities
集合:
老實說,我不明白為什么我在我的系統中為這個用戶獲得 ROLE_USER,因為它實際上在我的系統中具有 ADMIN 角色(角色是由我創建的)。
一般來說,我的應用程序中有 3 個角色:用戶、經理、管理員。 但無法理解如何為特殊用戶正確設置特定角色。
正因為如此,當我把 smth 像:
.antMatchers("/api/**").hasRole(Role.ADMIN.name())
.antMatchers("/administration/**").hasRole(Role.ADMIN.name())
據我了解,我得到了 403 cos,我為每個用戶得到了 ROLE_USER。
你能幫我為每個用戶設置角色,但從我的數據庫(不是谷歌的這個默認 ROLSER_USER)? 我還閱讀了有關 GrantedAuthorities 和 grantAuthorities 的映射器的信息,但對我來說有點不清楚。
我很高興聽到任何意見。 任何有用的鏈接來提高我對此的了解。 Cos 的主要目標:了解它是如何工作的。
下面是我的 oauth2 實現的其他類:
@Getter
@Setter
@RequiredArgsConstructor
public class CustomOidcUser implements OidcUser {
private final OidcUser oidcUser;
private String email;
private String firstName;
private String lastName;
@Override
public Map<String, Object> getClaims() {
return oidcUser.getClaims();
}
@Override
public OidcUserInfo getUserInfo() {
return oidcUser.getUserInfo();
}
@Override
public OidcIdToken getIdToken() {
return oidcUser.getIdToken();
}
@Override
public Map<String, Object> getAttributes() {
return oidcUser.getAttributes();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return oidcUser.getAuthorities();
}
@Override
public String getName() {
return oidcUser.getName();
}
}
@Service
@RequiredArgsConstructor
public class CustomOidcUserService extends OidcUserService {
private final UserRepository repository;
private static final String GOOGLE_KEY_LASTNAME = "family_name";
private static final String GOOGLE_KEY_FIRSTNAME = "given_name";
@Override
public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
final OidcUser oidcUser = super.loadUser(userRequest);
CustomOidcUser newUser = new CustomOidcUser(oidcUser);
String email = oidcUser.getAttributes().get("email").toString();
User user = createUserIfNoExist(email, oidcUser);
newUser.setEmail(email);
newUser.setFirstName(user.getFirstName());
newUser.setLastName(user.getLastName());
return newUser;
}
public User createUserIfNoExist(String email, OidcUser oidcUser) {
return repository.findByEmail(email)
.orElseGet(() -> {
User newUser = new User();
newUser.setEmail(email);
newUser.setRole(Role.USER);
newUser.setStartWorkAt(LocalDate.now());
newUser.setLastLoginDate(LocalDateTime.now());
...
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final AuthProvider authProvider;
private final OnSuccessHandler onSuccessHandler;
private final CustomOidcUserService customOidcUserService;
private final UserService userService;
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setUseReferer(true);
successHandler.setDefaultTargetUrl("/success");
successHandler.setAlwaysUseDefaultTargetUrl(true);
http
.addFilterAfter(new UserHasManagerFilter(userService), BasicAuthenticationFilter.class)
.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/api/**").hasRole(Role.ADMIN.name())
.antMatchers("/administration/**").hasRole(Role.ADMIN.name())
.and()
.httpBasic()
.and()
.formLogin()
.loginPage("/unauthorized")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/success")
.failureUrl("/failed")
.successHandler(successHandler)
.usernameParameter("email")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/logout_success")
.permitAll()
.and()
.oauth2Login()
.loginPage("/")
.userInfoEndpoint(userInfoEndpoint ->
userInfoEndpoint.oidcUserService(customOidcUserService)
.customUserType(CustomOidcUser.class, "google")
// .userAuthoritiesMapper(userAuthoritiesMapper())
)
.defaultSuccessUrl("/dashboard", true)
.successHandler(onSuccessHandler)
.failureHandler(authenticationFailureHandler())
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/**")
.permitAll();
}
對於 OIDC,默認情況下 Spring 將 map 范圍和默認 USER 角色授予 OidcUser object 上的授權。 您只需在您的 CustomOidcUser 中返回它
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return oidcUser.getAuthorities();
}
您需要在您的 CustomOidcUser object 中創建一個自定義的 GrantedAuthorities 集合,然后您的 CustomOidcUserService 您需要手動將數據庫中的角色添加到此集合中。
Collection<GrantedAuthority> authorities ....
authorities.add(new SimpleGrantedAuthority("ROLE_...."));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.