我为oauth2 auth服务器注册了多个客户端。假设 user1 对{strong> client1 具有ROLE_A
,ROLE_B
等角色,同一用户拥有ROLE_C
等{},{{1}等角色} client2 。现在,当用户使用 client1 或 client2 登录时,他可以看到所有四个角色,即。 ROLE_D
,ROLE_A
,ROLE_B
和ROLE_C
。
我的要求是当 user1 登录 client1 时,它应仅返回角色ROLE_D
和ROLE_A
。当他使用 client2 登录时,它应仅返回ROLE_B
和ROLE_C
为实现这一点,我计划的是在身份验证功能中,我需要获取clientId。所以使用clientId和用户名,我可以从db(client-user-roles-mapping表)中找到分配给用户的相应角色。但问题是我不知道如何在验证功能中获得 clientId
ROLE_D
任何人都可以帮助我
更新1
CustomAuthenticationProvider.java
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
String userName = ((String) authentication.getPrincipal()).toLowerCase();
String password = (String) authentication.getCredentials();
if (userName != null && authentication.getCredentials() != null) {
String clientId = // HERE HOW TO GET THE CLIENT ID
Set<String> userRoles = authRepository.getUserRoleDetails(userName.toLowerCase(), clientId);
Collection<SimpleGrantedAuthority> authorities = fillUserAuthorities(userRoles);
Authentication token = new UsernamePasswordAuthenticationToken(userName, StringUtils.EMPTY, authorities);
return token;
} else {
throw new BadCredentialsException("Authentication Failed!!!");
}
} else {
throw new BadCredentialsException("Username or Password cannot be empty!!!");
}
}
答案 0 :(得分:2)
以下是修改后的代码
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
String userName = ((String) authentication.getPrincipal()).toLowerCase();
String password = (String) authentication.getCredentials();
if (userName != null && authentication.getCredentials() != null) {
String clientId = getClientId();
// validate client ID before use
Set<String> userRoles = authRepository.getUserRoleDetails(userName.toLowerCase(), clientId);
Collection<SimpleGrantedAuthority> authorities = fillUserAuthorities(userRoles);
Authentication token = new UsernamePasswordAuthenticationToken(userName, StringUtils.EMPTY, authorities);
return token;
} else {
throw new BadCredentialsException("Authentication Failed!!!");
}
} else {
throw new BadCredentialsException("Username or Password cannot be empty!!!");
}
private String getClientId(){
final HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
final String authorizationHeaderValue = request.getHeader("Authorization");
final String base64AuthorizationHeader = Optional.ofNullable(authorizationHeaderValue)
.map(headerValue->headerValue.substring("Basic ".length())).orElse("");
if(StringUtils.isNotEmpty(base64AuthorizationHeader)){
String decodedAuthorizationHeader = new String(Base64.getDecoder().decode(base64AuthorizationHeader), Charset.forName("UTF-8"));
return decodedAuthorizationHeader.split(":")[0];
}
return "";
}
的更多信息
答案 1 :(得分:1)
UsernamePasswordAuthenticationToken
POJO不仅需要保存用户名和密码,还需要保存客户端标识符。
public ExtendedUsernamePasswordAuthenticationToken extends UsernamePasswordAuthenticationToken {
private final String clientId;
public ExtendedUsernamePasswordAuthenticationToken(Object principal
, Object credentials
, String clientId) {
super(principal, credentials);
this.clientId = clientId;
}
public String getClientId() { return clientId; }
}
UsernamePasswordAuthenticationFilter
需要调整身份验证过程,以便除了用户名和密码之外,还将客户端标识符传递给身份验证代码。
public class ExtendedUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
public ExtendedUsernamePasswordAuthenticationFilter () { super(); }
@Override
public public Authentication attemptAuthentication(HttpServletRequest request
, HttpServletResponse response)
throws AuthenticationException {
// See the source code of UsernamePasswordAuthenticationFilter
// to implement this. Instead of creating an instance of
// UsernamePasswordAuthenticationToken, create an instance of
// ExtendedUsernamePasswordAuthenticationToken, something along
// the lines of:
final String username = obtainUsername(request);
final String password = obtainPassword(request);
final String clientId = obtainClientId(request);
...
final Authentication authentication = new ExtendedUsernamePasswordAuthenticationToken(username, password, clientId);
return getAuthenticationManager().authenticate(authentication);
}
}
public CustomAuthenticationProvider implements AuthenticationProvider {
...
@Override
public boolean supports(final Class<?> authentication) {
return authentication.isAssignableFrom(ExtendedUsernamePasswordAuthenticationToken.class);
}
@Override
public Authentication authenticate(final Authentication authentication)
throws AuthenticationException {
}
}
<bean class="com.path.to.filter.ExtendedUsernamePasswordAuthenticationFilter" id="formAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<http ... >
<security:custom-filter position="FORM_LOGIN_FILTER" ref="formAuthenticationFilter"/>
...
</http>
或者,如果使用Java配置:
@Bean
public ExtendedUsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter(final AuthenticationManager authenticationManager) {
final ExtendedUsernamePasswordAuthenticationFilter filter = new ExtendedUsernamePasswordAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager);
return filter;
}
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAt(usernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
...
}
答案 2 :(得分:1)
根据您的要求,由于您只想从请求中访问其他参数,因此您可以在 $ldate="";
while($row = $result->fetch_assoc()){
$lamt=$row['Loan_Amount'];
$today=time();
if(empty(strtotime($row['loan_date1']))){
$timespan=(time()-strtotime($row['Loan_Date']))/(60*60*24);
$month=round($timespan/31);
$ldate=$row['Loan_Date'];}
if(strtotime($row['loan_date1'])>0 and empty(strtotime($row['loan_date2']))){
$timespan=(time()-strtotime($row['loan_date1']))/(60*60*24);
$month=round($timespan/31);
$ldate=$row['loan_date1']; }
Print '<td align="center" style="width:100px;">'.date("d M Y",strtotime($ldate)). "</td>";
课程中试用以下内容
CustomAuthenticationProvider
添加以下逻辑以读取httpRequest参数并添加逻辑以访问授权密钥
@Autowired
private HttpServletRequest request;
现在,您将拥有编码基本身份验证字段,您可以像下面那样解码
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println("Header Name - " + headerName + ", Value - " + request.getHeader(headerName));
}
}