![](/img/trans.png)
[英]Spring Security 5.3.2 OAuth 2, Resource Owner Password Credentials Flow - How to add additional HEADER parameters to authorization server uri
[英]Central auth server with multiple clients using resource owner password credentials oauth flow
我進行了以下設置:
我有一個現成的應用程序(上面的app1)是jsf 2.2,並配置了用於登錄目的的spring security。 該應用程序現在擁有自己的用戶群,可以獨立運行。
這是我嘗試獲取的流程: 資源所有者密碼憑據OAuth流程
所以我們想要:
我是這個oauth2.0進程的新手(真的是spring),但是我認為這是我想要的流程。 如何使用Spring Security進行設置? 我已經看到了我們認為需要的名為oauth2login()的安全設置,但是我認為這是更多的授權代碼流程。
使用密碼流,我還沒有找到一個很好的例子。
我確實信任此過程中的每個應用程序,因此密碼流程也很可靠。 我們控制維護身份驗證服務器和其他應用程序之間流量的網絡。
編輯 :由於需求和我們的客戶群的緣故,不能選擇SSO。 這些應用程序足夠獨特,以至於毫無意義,但是用戶應該能夠使用這些憑據登錄到我們的任何應用程序中。
編輯2 :對不起,第二次編輯。 我想補充一點,我已經在app1上添加了一個資源配置,並且看起來似乎可以正常工作-我已經保護了/ views / *的所有內容,並且當我嘗試使用它們時,我得到了預期的“需要完整身份驗證”消息。
編輯3 :我認為我正在取得一些進步-
首先,我創建了一個實現AuthenticationProvider的spring組件,然后重寫了authenticate方法,以便創建具有我所有屬性(客戶端ID,客戶端機密,授予類型,范圍等)的ResourceOwnerPasswordResourceDetails對象,並調用授權服務器以獲取令牌。 我很高興看到授權服務器的日志刷新。
下一步,我需要弄清楚如何生成org.springframework.security.core.userdetails.User擴展,以便為用戶存儲特權。
另外-我還不太清楚令牌的存儲方式。 我知道身份驗證服務器會生成令牌並將其存儲在jdbc中,但是令牌在哪里/如何存儲在客戶端?
對於那些好奇的人,這是我在客戶端(app1)上設置身份驗證提供程序的方式。 我仍然對資源服務器有問題(請問一個單獨的問題),但這是我所做的:
定制驗證器:
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private AppUserDAO appUserDAO;
private String accessTokenUri = "http://localhost:8080/oauth/token";
private String clientId = "clientid";
private String clientSecret = "clientsecret";
public AccessTokenProvider userAccessTokenProvider() {
ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
return accessTokenProvider;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
final String username = authentication.getName();
final String password = authentication.getCredentials().toString();
List<String> scopes = new ArrayList<String>();
scopes.add("read");
final ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setUsername(username);
resource.setPassword(password);
resource.setAccessTokenUri(accessTokenUri);
resource.setClientId(clientId);
resource.setClientSecret(clientSecret);
resource.setGrantType("password");
resource.setScope(scopes);
// Generate an access token
final OAuth2RestTemplate template = new OAuth2RestTemplate(resource, new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest()));
template.setAccessTokenProvider(userAccessTokenProvider());
OAuth2AccessToken accessToken = null;
try {
accessToken = template.getAccessToken();
System.out.println("Grabbed access token from " + accessTokenUri);
}
catch (OAuth2AccessDeniedException e) {
if (e.getCause() instanceof ResourceAccessException) {
final String errorMessage = String.format(
"While authenticating user '%s': " + "Unable to access accessTokenUri '%s'.", username,
accessTokenUri);
throw new AuthenticationServiceException(errorMessage, e);
}
throw new BadCredentialsException(String.format("Access denied for user '%s'.", username), e);
}
catch (OAuth2Exception e) {
throw new AuthenticationServiceException(
String.format("Unable to perform OAuth authentication for user '%s'.", username), e);
}
// Determine roles for user
List<GrantedAuthority> grantList = ...
// Create custom user for the principal
User user = .....
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, null /*dont store password*/, grantList);
return token;
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProvider authProvider;
....
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.