OAuth 10a deals with roal based authorization.
Can we do the permission based authorization with oauth 10a ?
That is can we authorize a URL pattern, can we authorize frequency of request URL
Or can we authorize particulate client IP to access the resource
The easiest way is to write a custom expression voter as below
public class CExpressionVoter implements AccessDecisionVoter<FilterInvocation> {
public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
assert authentication != null;
assert fi != null;
assert attributes != null;
if(authentication.getPrincipal()!=null ) {
Object principal = authentication.getPrincipal();
if(principal instanceof UserDetails) {
UserDetails userDetails = (UserDetails)principal;
if(userDetails.getUsername().equalsIgnoreCase("anonymousUser")){
return -1;
} else {
Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
int i = -1;
for (GrantedAuthority grantedAuthority : authorities) {
String uriAuthorityPattern = grantedAuthority.getAuthority().toLowerCase();
String uriRequest = fi.getRequestUrl().toLowerCase();
String fullRequestUrl = fi.getFullRequestUrl();
String delimiters = "/\\s*|\\?\\s*";
String[] uriPatternArray = uriRequest.split(delimiters);
String uriPattern = null;
if(uriPatternArray !=null & uriPatternArray.length >=2) {
uriPattern = uriPatternArray[1];
}
// This is the sample to check the URL pattern. Likewise you can do other authentications, All the autorities can be loaded to
// user detail object using a custom user detail service, sample given below
if (uriPattern!=null & uriPattern.equalsIgnoreCase(uriAuthorityPattern)){
i = 1; break;
} else {
i = -1;
}
}
return i;
}
}
if (principal instanceof String) {
if(((String) principal).equalsIgnoreCase("anonymousUser")){
return -1;
}
}
}
return 1;
}
public boolean supports(ConfigAttribute attribute) {
return true;
}
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(FilterInvocation.class);
}
}
Custom User Detail Service
public class CUserDetailService implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
ArrayList<String> authority = new ArrayList<String>();
// Get the values from the database and add as arrayList
UserDetails result = new CustomUserDetails(findById, authority);
return result;
}
}
Custom User Details
public class CustomUserDetails implements UserDetails {
private String userName;
private String password;
private Collection<GrantedAuthority> grantedAuthorities;
public CustomUserDetails(CustomUser user, List<String> authority){
this.grantedAuthorities = new ArrayList<GrantedAuthority>();
for (String p : authority) {
GrantedAuthority ga = new SimpleGrantedAuthority(p);
this.grantedAuthorities.add(ga);
}
}
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.grantedAuthorities;
}
// write inherited methods for UserDetails
}
Custom Secure Resource Filter
// this is a dummy implementation
public class CSecureResourceFilter implements FilterInvocationSecurityMetadataSource {
public Collection<ConfigAttribute> getAllConfigAttributes() {
StringBuilder rolesStringBuilder = new StringBuilder();
rolesStringBuilder.append("USER1");
List<ConfigAttribute> createListFromCommaDelimitedString = SecurityConfig.createListFromCommaDelimitedString(rolesStringBuilder.toString());
return createListFromCommaDelimitedString;
}
public Collection<ConfigAttribute> getAttributes(Object filter) throws IllegalArgumentException {
StringBuilder rolesStringBuilder = new StringBuilder();
rolesStringBuilder.append("USER1");
return SecurityConfig.createListFromCommaDelimitedString(rolesStringBuilder.toString());
}
public boolean supports(Class<?> arg0) {
return true;
}
}
Spring security configuration file
..
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg name="decisionVoters">
<beans:list>
<beans:bean class="..................CExpressionVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
<http use-expressions="true" auto-config='true' access-denied-page="/login.jsp" >
<form-login authentication-failure-url="/login.jsp" default-target-url="/index.jsp" login-page="/login.jsp" login-processing-url="/login.do" />
<custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="filterSecurityInterceptor" />
</http>
<beans:bean id="customUserDetailService" class=".....CUserDetailService" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailService"/>
</authentication-manager>
<beans:bean id="customSecureResourceFilter" class=".......CSecureResourceFilter"/>
<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
<beans:property name="securityMetadataSource" ref="customSecureResourceFilter"/>
</beans:bean>
Can we do the permission based authorization with oauth 10a ?
That is can we authorize a URL pattern, can we authorize frequency of request URL
Or can we authorize particulate client IP to access the resource
The easiest way is to write a custom expression voter as below
public class CExpressionVoter implements AccessDecisionVoter<FilterInvocation> {
public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
assert authentication != null;
assert fi != null;
assert attributes != null;
if(authentication.getPrincipal()!=null ) {
Object principal = authentication.getPrincipal();
if(principal instanceof UserDetails) {
UserDetails userDetails = (UserDetails)principal;
if(userDetails.getUsername().equalsIgnoreCase("anonymousUser")){
return -1;
} else {
Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
int i = -1;
for (GrantedAuthority grantedAuthority : authorities) {
String uriAuthorityPattern = grantedAuthority.getAuthority().toLowerCase();
String uriRequest = fi.getRequestUrl().toLowerCase();
String fullRequestUrl = fi.getFullRequestUrl();
String delimiters = "/\\s*|\\?\\s*";
String[] uriPatternArray = uriRequest.split(delimiters);
String uriPattern = null;
if(uriPatternArray !=null & uriPatternArray.length >=2) {
uriPattern = uriPatternArray[1];
}
// This is the sample to check the URL pattern. Likewise you can do other authentications, All the autorities can be loaded to
// user detail object using a custom user detail service, sample given below
if (uriPattern!=null & uriPattern.equalsIgnoreCase(uriAuthorityPattern)){
i = 1; break;
} else {
i = -1;
}
}
return i;
}
}
if (principal instanceof String) {
if(((String) principal).equalsIgnoreCase("anonymousUser")){
return -1;
}
}
}
return 1;
}
public boolean supports(ConfigAttribute attribute) {
return true;
}
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(FilterInvocation.class);
}
}
Custom User Detail Service
public class CUserDetailService implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
ArrayList<String> authority = new ArrayList<String>();
// Get the values from the database and add as arrayList
UserDetails result = new CustomUserDetails(findById, authority);
return result;
}
}
Custom User Details
public class CustomUserDetails implements UserDetails {
private String userName;
private String password;
private Collection<GrantedAuthority> grantedAuthorities;
public CustomUserDetails(CustomUser user, List<String> authority){
this.grantedAuthorities = new ArrayList<GrantedAuthority>();
for (String p : authority) {
GrantedAuthority ga = new SimpleGrantedAuthority(p);
this.grantedAuthorities.add(ga);
}
}
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.grantedAuthorities;
}
// write inherited methods for UserDetails
}
Custom Secure Resource Filter
// this is a dummy implementation
public class CSecureResourceFilter implements FilterInvocationSecurityMetadataSource {
public Collection<ConfigAttribute> getAllConfigAttributes() {
StringBuilder rolesStringBuilder = new StringBuilder();
rolesStringBuilder.append("USER1");
List<ConfigAttribute> createListFromCommaDelimitedString = SecurityConfig.createListFromCommaDelimitedString(rolesStringBuilder.toString());
return createListFromCommaDelimitedString;
}
public Collection<ConfigAttribute> getAttributes(Object filter) throws IllegalArgumentException {
StringBuilder rolesStringBuilder = new StringBuilder();
rolesStringBuilder.append("USER1");
return SecurityConfig.createListFromCommaDelimitedString(rolesStringBuilder.toString());
}
public boolean supports(Class<?> arg0) {
return true;
}
}
Spring security configuration file
..
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg name="decisionVoters">
<beans:list>
<beans:bean class="..................CExpressionVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
<http use-expressions="true" auto-config='true' access-denied-page="/login.jsp" >
<form-login authentication-failure-url="/login.jsp" default-target-url="/index.jsp" login-page="/login.jsp" login-processing-url="/login.do" />
<custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="filterSecurityInterceptor" />
</http>
<beans:bean id="customUserDetailService" class=".....CUserDetailService" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailService"/>
</authentication-manager>
<beans:bean id="customSecureResourceFilter" class=".......CSecureResourceFilter"/>
<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
<beans:property name="securityMetadataSource" ref="customSecureResourceFilter"/>
</beans:bean>
No comments:
Post a Comment