added authority for subject-issuer authorities and associated mapper, addresses #234

pull/324/merge
Justin Richer 2013-04-19 15:39:43 -04:00
parent 29aa0f2be6
commit 0e9273fd08
3 changed files with 196 additions and 4 deletions

View File

@ -0,0 +1,81 @@
/**
*
*/
package org.mitre.openid.connect.client;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
/**
*
* Simple mapper that adds ROLE_USER to the authorities map for all queries,
* plus adds ROLE_ADMIN if the subject and issuer pair are found in the
* configurable "admins" set.
*
* @author jricher
*
*/
public class NamedAdminAuthoritiesMapper implements GrantedAuthoritiesMapper {
private static final SimpleGrantedAuthority ROLE_ADMIN = new SimpleGrantedAuthority("ROLE_ADMIN");
private static final SimpleGrantedAuthority ROLE_USER = new SimpleGrantedAuthority("ROLE_USER");
private Set<SubjectIssuerGrantedAuthority> admins = new HashSet<SubjectIssuerGrantedAuthority>();
private GrantedAuthoritiesMapper chain = new NullAuthoritiesMapper();
@Override
public Collection<? extends GrantedAuthority> mapAuthorities(Collection<? extends GrantedAuthority> authorities) {
Set<GrantedAuthority> out = new HashSet<GrantedAuthority>();
out.addAll(authorities);
for (GrantedAuthority authority : authorities) {
if (admins.contains(authority)) {
out.add(ROLE_ADMIN);
}
}
// everybody's a user by default
out.add(ROLE_USER);
return chain.mapAuthorities(out);
}
/**
* @return the admins
*/
public Set<SubjectIssuerGrantedAuthority> getAdmins() {
return admins;
}
/**
* @param admins the admins to set
*/
public void setAdmins(Set<SubjectIssuerGrantedAuthority> admins) {
this.admins = admins;
}
/**
* @return the chain
*/
public GrantedAuthoritiesMapper getChain() {
return chain;
}
/**
* @param chain the chain to set
*/
public void setChain(GrantedAuthoritiesMapper chain) {
this.chain = chain;
}
}

View File

@ -22,12 +22,14 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
/**
@ -39,7 +41,7 @@ public class OIDCAuthenticationProvider implements
private UserInfoFetcher userInfoFetcher = new UserInfoFetcher();
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
private GrantedAuthoritiesMapper authoritiesMapper = new NamedAdminAuthoritiesMapper();
/*
* (non-Javadoc)
@ -67,12 +69,11 @@ public class OIDCAuthenticationProvider implements
if (authentication instanceof OIDCAuthenticationToken) {
// Default authorities set
// TODO: let this be configured
Collection<SimpleGrantedAuthority> authorities = Sets.newHashSet(new SimpleGrantedAuthority("ROLE_USER"));
OIDCAuthenticationToken token = (OIDCAuthenticationToken) authentication;
Collection<SubjectIssuerGrantedAuthority> authorities = Lists.newArrayList(new SubjectIssuerGrantedAuthority(token.getSub(), token.getIssuer()));
UserInfo userInfo = userInfoFetcher.loadUserInfo(token);
if (userInfo == null) {

View File

@ -0,0 +1,110 @@
/**
*
*/
package org.mitre.openid.connect.client;
import org.springframework.security.core.GrantedAuthority;
import com.google.common.base.Strings;
/**
*
* Simple authority representing a user at an issuer.
*
* @author jricher
*
*/
public class SubjectIssuerGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = 5584978219226664794L;
private final String subject;
private final String issuer;
/**
* @param subject
* @param issuer
*/
public SubjectIssuerGrantedAuthority(String subject, String issuer) {
if (Strings.isNullOrEmpty(subject) || Strings.isNullOrEmpty(issuer)) {
throw new IllegalArgumentException("Neither subject nor issuer may be null or empty");
}
this.subject = subject;
this.issuer = issuer;
}
/**
* Returns a string formed by concatenating the subject with the issuer, separated by _ and prepended with OIDC_
*
* For example, the user "bob" from issuer "http://id.example.com/" would return the authority string of:
*
* OIDC_bob_http://id.example.com/
*/
@Override
public String getAuthority() {
return "OIDC_" + subject + "_" + issuer;
}
/**
* @return the subject
*/
public String getSubject() {
return subject;
}
/**
* @return the issuer
*/
public String getIssuer() {
return issuer;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((issuer == null) ? 0 : issuer.hashCode());
result = prime * result + ((subject == null) ? 0 : subject.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof SubjectIssuerGrantedAuthority)) {
return false;
}
SubjectIssuerGrantedAuthority other = (SubjectIssuerGrantedAuthority) obj;
if (issuer == null) {
if (other.issuer != null) {
return false;
}
} else if (!issuer.equals(other.issuer)) {
return false;
}
if (subject == null) {
if (other.subject != null) {
return false;
}
} else if (!subject.equals(other.subject)) {
return false;
}
return true;
}
@Override
public String toString() {
return getAuthority();
}
}