finish up work on moving backend into stateless server with resource-oriented api using basic auth for securing api calls.

This commit is contained in:
Keith Woodlock
2012-05-17 15:11:49 +01:00
parent 45965a3f50
commit 93678bf9ce
52 changed files with 150 additions and 2902 deletions
+3 -1
View File
@@ -64,7 +64,9 @@ dependencies {
[group: 'org.springframework', name: 'spring-aspects', version: springVersion],
[group: 'org.springframework', name: 'spring-web', version: springVersion],
[group: 'org.springframework', name: 'spring-webmvc', version: springVersion],
[group: 'org.springframework.security.oauth', name: 'spring-security-oauth', version: springSecurityOauthVersion],
[group: 'org.springframework.security', name: 'spring-security-core', version: springSecurityVersion],
[group: 'org.springframework.security', name: 'spring-security-web', version: springSecurityVersion],
[group: 'org.springframework.security', name: 'spring-security-config', version: springSecurityVersion],
[group: 'org.springframework.security', name: 'spring-security-taglibs', version: springSecurityVersion],
[group: 'org.aspectj', name: 'aspectjrt', version: '1.6.11.RELEASE'],
@@ -1,93 +0,0 @@
package org.mifosng.oauth;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
public class ConsumerUserDetails implements UserDetails {
private final String username;
private final Collection<GrantedAuthority> authorities;
public ConsumerUserDetails(String username, Collection<GrantedAuthority> authorities) {
this.username = username;
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return "";
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public boolean hasNoReportingAuthority() {
return !hasReportingAuthority();
}
private boolean hasReportingAuthority() {
SimpleGrantedAuthority reportingAuthority = new SimpleGrantedAuthority("REPORTING_SUPER_USER_ROLE");
return this.authorities.contains(reportingAuthority);
}
public boolean hasNoAuthorityToSumitLoanApplication() {
return !hasAuthorityToSumitLoanApplication();
}
private boolean hasAuthorityToSumitLoanApplication() {
return containsAnyOf(portfolioAllAuthority(), sumbitLoanApplicationAuthority(), sumbitHistoricLoanApplicationAuthority());
}
private boolean containsAnyOf(SimpleGrantedAuthority... authorities) {
boolean match = false;
for (SimpleGrantedAuthority authority : authorities) {
match = this.authorities.contains(authority);
if (match) {
break;
}
}
return match;
}
private SimpleGrantedAuthority portfolioAllAuthority() {
return new SimpleGrantedAuthority("PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE");
}
private SimpleGrantedAuthority sumbitLoanApplicationAuthority() {
return new SimpleGrantedAuthority("CAN_SUBMIT_NEW_LOAN_APPLICATION_ROLE");
}
private SimpleGrantedAuthority sumbitHistoricLoanApplicationAuthority() {
return new SimpleGrantedAuthority("CAN_SUBMIT_HISTORIC_LOAN_APPLICATION_ROLE");
}
}
@@ -1,271 +0,0 @@
package org.mifosng.oauth;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.mifosng.configuration.ApplicationConfigurationService;
import org.mifosng.data.AuthenticatedUserData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth.common.OAuthProviderParameter;
import org.springframework.security.oauth.consumer.OAuthConsumerToken;
import org.springframework.security.oauth.consumer.OAuthRequestFailedException;
import org.springframework.security.oauth.consumer.OAuthSecurityContextHolder;
import org.springframework.security.oauth.consumer.OAuthSecurityContextImpl;
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
import org.springframework.security.oauth.consumer.client.CoreOAuthConsumerSupport;
import org.springframework.security.oauth.consumer.filter.OAuthConsumerContextFilter;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.web.client.HttpStatusCodeException;
public class CustomOAuthConsumerContextFilter extends OAuthConsumerContextFilter {
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
private final ApplicationConfigurationService applicationConfigurationService;
@Autowired
public CustomOAuthConsumerContextFilter(final ApplicationConfigurationService applicationConfigurationService) {
this.applicationConfigurationService = applicationConfigurationService;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
OAuthSecurityContextImpl context = new OAuthSecurityContextImpl();
context.setDetails(request);
Map<String, OAuthConsumerToken> rememberedTokens = getRememberMeServices().loadRememberedTokens(request, response);
Map<String, OAuthConsumerToken> accessTokens = new TreeMap<String, OAuthConsumerToken>();
Map<String, OAuthConsumerToken> requestTokens = new TreeMap<String, OAuthConsumerToken>();
if (rememberedTokens != null) {
for (Map.Entry<String, OAuthConsumerToken> tokenEntry : rememberedTokens.entrySet()) {
OAuthConsumerToken token = tokenEntry.getValue();
if (token != null) {
if (token.isAccessToken()) {
accessTokens.put(tokenEntry.getKey(), token);
}
else {
requestTokens.put(tokenEntry.getKey(), token);
}
}
}
}
context.setAccessTokens(accessTokens);
OAuthSecurityContextHolder.setContext(context);
// if (LOG.isDebugEnabled()) {
// LOG.debug("Storing access tokens in request attribute '" + getAccessTokensRequestAttribute() + "'.");
// }
try {
try {
request.setAttribute(getAccessTokensRequestAttribute(), new ArrayList<OAuthConsumerToken>(accessTokens.values()));
chain.doFilter(request, response);
}
catch (Exception e) {
try {
ProtectedResourceDetails resourceThatNeedsAuthorization = checkForResourceThatNeedsAuthorization(e);
String neededResourceId = resourceThatNeedsAuthorization.getId();
while (!accessTokens.containsKey(neededResourceId)) {
OAuthConsumerToken token = requestTokens.remove(neededResourceId);
if (token == null) {
token = getTokenServices().getToken(neededResourceId);
}
String verifier = request.getParameter(OAuthProviderParameter.oauth_verifier.toString());
// if the token is null OR
// if there is NO access token and (we're not using 1.0a or the verifier is not null)
if (token == null || (!token.isAccessToken() && (!resourceThatNeedsAuthorization.isUse10a() || verifier == null))) {
//no token associated with the resource, start the oauth flow.
//if there's a request token, but no verifier, we'll assume that a previous oauth request failed and we need to get a new request token.
// if (LOG.isDebugEnabled()) {
// LOG.debug("Obtaining request token for resource: " + neededResourceId);
// }
//obtain authorization.
String callbackURL = response.encodeRedirectURL(getCallbackURL(request));
token = getConsumerSupport().getUnauthorizedRequestToken(neededResourceId, callbackURL);
// if (LOG.isDebugEnabled()) {
// LOG.debug("Request token obtained for resource " + neededResourceId + ": " + token);
// }
//okay, we've got a request token, now we need to authorize it.
requestTokens.put(neededResourceId, token);
getTokenServices().storeToken(neededResourceId, token);
try {
String baseURL = this.applicationConfigurationService.retrieveOAuthProviderDetails().getUserAuthorizationUrl();
StringBuilder builder = new StringBuilder(baseURL);
char appendChar = baseURL.indexOf('?') < 0 ? '?' : '&';
builder.append(appendChar).append("oauth_token=");
builder.append(URLEncoder.encode(token.getValue(), "UTF-8"));
builder.append('&').append("oauth_callback=");
builder.append(URLEncoder.encode(callbackURL, "UTF-8"));
String redirect = builder.toString();
request.setAttribute("org.springframework.security.oauth.consumer.AccessTokenRequiredException", e);
this.redirectStrategy.sendRedirect(request, response, redirect);
return;
}
catch (UnsupportedEncodingException use) {
throw new IllegalStateException(use);
}
}
else if (!token.isAccessToken()) {
//we have a presumably authorized request token, let's try to get an access token with it.
// if (LOG.isDebugEnabled()) {
// LOG.debug("Obtaining access token for resource: " + neededResourceId);
// }
//authorize the request token and store it.
try {
token = getConsumerSupport().getAccessToken(token, verifier);
}
finally {
getTokenServices().removeToken(neededResourceId);
}
// if (LOG.isDebugEnabled()) {
// LOG.debug("Access token " + token + " obtained for resource " + neededResourceId + ". Now storing and using.");
// }
getTokenServices().storeToken(neededResourceId, token);
}
accessTokens.put(neededResourceId, token);
// hack here to detect this situation which happens once user is authenticated successfully on provider
// and redirected back to this client application
String oauthAccessToken = request.getParameter("oauth_token");
String oauthVerifier = request.getParameter("oauth_verifier");
if (StringUtils.isNotBlank(oauthAccessToken) && StringUtils.isNotBlank(oauthVerifier)) {
CoreOAuthConsumerSupport support = (CoreOAuthConsumerSupport)getConsumerSupport();
MifosNgOauthRestTemplate oauthRestTemplate = new MifosNgOauthRestTemplate(support.getProtectedResourceDetailsService());
try {
URI restUri = URI
.create(getBaseServerUrl().concat("api/protected/user/"
+ oauthAccessToken));
ResponseEntity<AuthenticatedUserData> s = oauthRestTemplate.exchange(restUri, HttpMethod.GET, emptyRequest(), AuthenticatedUserData.class);
AuthenticatedUserData userData = s.getBody();
SecurityContextHolder.clearContext();
SecurityContext springSecurityContext = new SecurityContextImpl();
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
for (String permissionCode : userData.getPermissions()) {
authorities.add(new SimpleGrantedAuthority(permissionCode));
}
UserDetails principal = new ConsumerUserDetails(userData.getUsername(), authorities);
Authentication auth = new UsernamePasswordAuthenticationToken(principal, principal, principal.getAuthorities());
springSecurityContext.setAuthentication(auth);
SecurityContextHolder.setContext(springSecurityContext);
} catch (HttpStatusCodeException ex) {
System.err.println(ex.getResponseBodyAsString());
throw ex;
}
}
try {
//try again
if (!response.isCommitted()) {
request.setAttribute(getAccessTokensRequestAttribute(), new ArrayList<OAuthConsumerToken>(accessTokens.values()));
chain.doFilter(request, response);
}
else {
//dang. what do we do now?
throw new IllegalStateException("Unable to reprocess filter chain with needed OAuth2 resources because the response is already committed.");
}
}
catch (Exception e1) {
resourceThatNeedsAuthorization = checkForResourceThatNeedsAuthorization(e1);
neededResourceId = resourceThatNeedsAuthorization.getId();
}
}
}
catch (OAuthRequestFailedException eo) {
fail(request, response, eo);
}
catch (Exception ex) {
Throwable[] causeChain = getThrowableAnalyzer().determineCauseChain(ex);
OAuthRequestFailedException rfe = (OAuthRequestFailedException) getThrowableAnalyzer().getFirstThrowableOfType(OAuthRequestFailedException.class, causeChain);
if (rfe != null) {
fail(request, response, rfe);
}
else {
// Rethrow ServletExceptions and RuntimeExceptions as-is
if (ex instanceof ServletException) {
throw (ServletException) ex;
}
else if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
// Wrap other Exceptions. These are not expected to happen
throw new RuntimeException(ex);
}
}
}
}
finally {
OAuthSecurityContextHolder.setContext(null);
HashMap<String, OAuthConsumerToken> tokensToRemember = new HashMap<String, OAuthConsumerToken>();
tokensToRemember.putAll(requestTokens);
tokensToRemember.putAll(accessTokens);
getRememberMeServices().rememberTokens(tokensToRemember, request, response);
}
}
private HttpEntity<Object> emptyRequest() {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Accept", "application/xml");
requestHeaders.set("Content-Type", "application/xml");
HttpEntity<Object> requestEntity = new HttpEntity<Object>(
requestHeaders);
return requestEntity;
}
private String getBaseServerUrl() {
return this.applicationConfigurationService.retrieveOAuthProviderDetails().getProviderBaseUrl();
}
}
@@ -1,67 +0,0 @@
package org.mifosng.oauth;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth.consumer.AccessTokenRequiredException;
import org.springframework.security.oauth.consumer.OAuthConsumerToken;
import org.springframework.security.oauth.consumer.OAuthSecurityContext;
import org.springframework.security.oauth.consumer.OAuthSecurityContextHolder;
import org.springframework.security.oauth.consumer.filter.OAuthConsumerProcessingFilter;
public class CustomOAuthConsumerProcessingFilter extends
OAuthConsumerProcessingFilter {
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
Set<String> accessTokenDeps = getAccessTokenDependencies(request,
response, chain);
if (!accessTokenDeps.isEmpty()) {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (isRequireAuthenticated() && !authentication.isAuthenticated()) {
throw new InsufficientAuthenticationException(
"An authenticated principal must be present.");
}
OAuthSecurityContext context = OAuthSecurityContextHolder
.getContext();
if (context == null) {
throw new IllegalStateException(
"No OAuth security context has been established. Unable to access resources.");
}
Map<String, OAuthConsumerToken> accessTokens = context
.getAccessTokens();
for (String dependency : accessTokenDeps) {
if (!accessTokens.containsKey(dependency)) {
throw new AccessTokenRequiredException(
getProtectedResourceDetailsService()
.loadProtectedResourceDetailsById(
dependency));
}
}
chain.doFilter(request, response);
} else {
chain.doFilter(servletRequest, servletResponse);
}
}
}
@@ -1,228 +0,0 @@
package org.mifosng.oauth;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.oauth.common.OAuthProviderParameter;
import org.springframework.security.oauth.consumer.OAuthConsumerToken;
import org.springframework.security.oauth.consumer.OAuthRequestFailedException;
import org.springframework.security.oauth.consumer.OAuthSecurityContextHolder;
import org.springframework.security.oauth.consumer.OAuthSecurityContextImpl;
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
import org.springframework.security.oauth.consumer.filter.OAuthConsumerContextFilter;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
public class MifosNgOauthConsumerContextFilter extends OAuthConsumerContextFilter {
private static final Log LOG = LogFactory.getLog(MifosNgOauthConsumerContextFilter.class);
private RestTemplate noAuthRestTemplate;
@Override
public void doFilter(final ServletRequest servletRequest,
final ServletResponse servletResponse, final FilterChain chain)
throws IOException, ServletException {
ResponseErrorHandler defaultResponseErrorHandler = new DefaultResponseErrorHandler();
this.noAuthRestTemplate = new RestTemplate();
this.noAuthRestTemplate.setErrorHandler(defaultResponseErrorHandler);
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
OAuthSecurityContextImpl context = new OAuthSecurityContextImpl();
context.setDetails(request);
Map<String, OAuthConsumerToken> rememberedTokens = getRememberMeServices()
.loadRememberedTokens(request, response);
Map<String, OAuthConsumerToken> accessTokens = new TreeMap<String, OAuthConsumerToken>();
Map<String, OAuthConsumerToken> requestTokens = new TreeMap<String, OAuthConsumerToken>();
if (rememberedTokens != null) {
for (Map.Entry<String, OAuthConsumerToken> tokenEntry : rememberedTokens
.entrySet()) {
OAuthConsumerToken token = tokenEntry.getValue();
if (token != null) {
if (token.isAccessToken()) {
accessTokens.put(tokenEntry.getKey(), token);
} else {
requestTokens.put(tokenEntry.getKey(), token);
}
}
}
}
context.setAccessTokens(accessTokens);
OAuthSecurityContextHolder.setContext(context);
if (LOG.isDebugEnabled()) {
LOG.debug("Storing access tokens in request attribute '"
+ getAccessTokensRequestAttribute() + "'.");
}
try {
try {
request.setAttribute(
getAccessTokensRequestAttribute(),
new ArrayList<OAuthConsumerToken>(accessTokens.values()));
chain.doFilter(request, response);
} catch (Exception e) {
try {
ProtectedResourceDetails resourceThatNeedsAuthorization = checkForResourceThatNeedsAuthorization(e);
String neededResourceId = resourceThatNeedsAuthorization
.getId();
while (!accessTokens.containsKey(neededResourceId)) {
OAuthConsumerToken token = requestTokens
.remove(neededResourceId);
if (token == null) {
token = getTokenServices().getToken(
neededResourceId);
}
String verifier = request
.getParameter(OAuthProviderParameter.oauth_verifier
.toString());
// if the token is null OR
// if there is NO access token and (we're not using 1.0a
// or the verifier is not null)
if (token == null
|| !token.isAccessToken()
&& (!resourceThatNeedsAuthorization.isUse10a() || verifier == null)) {
// no token associated with the resource, start the
// oauth flow.
// if there's a request token, but no verifier,
// we'll assume that a previous oauth request failed
// and we need to get a new request token.
if (LOG.isDebugEnabled()) {
LOG.debug("Obtaining request token for resource: "
+ neededResourceId);
}
// obtain authorization.
String callbackURL = response
.encodeRedirectURL(getCallbackURL(request));
token = getConsumerSupport()
.getUnauthorizedRequestToken(
neededResourceId, callbackURL);
if (LOG.isDebugEnabled()) {
LOG.debug("Request token obtained for resource "
+ neededResourceId + ": " + token);
}
// okay, we've got a request token, now we need to
// authorize it.
requestTokens.put(neededResourceId, token);
getTokenServices().storeToken(neededResourceId,
token);
String redirect = getUserAuthorizationRedirectURL(
resourceThatNeedsAuthorization, token,
callbackURL);
if (LOG.isDebugEnabled()) {
LOG.debug("Redirecting request to "
+ redirect
+ " for user authorization of the request token for resource "
+ neededResourceId + ".");
}
request.setAttribute(
"org.springframework.security.oauth.consumer.AccessTokenRequiredException",
e);
getRedirectStrategy().sendRedirect(request,
response, redirect);
return;
} else if (!token.isAccessToken()) {
// we have a presumably authorized request token,
// let's try to get an access token with it.
if (LOG.isDebugEnabled()) {
LOG.debug("Obtaining access token for resource: "
+ neededResourceId);
}
// authorize the request token and store it.
try {
token = getConsumerSupport().getAccessToken(
token, verifier);
} finally {
getTokenServices()
.removeToken(neededResourceId);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Access token " + token
+ " obtained for resource "
+ neededResourceId
+ ". Now storing and using.");
}
getTokenServices().storeToken(neededResourceId,
token);
}
accessTokens.put(neededResourceId, token);
try {
// try again
if (!response.isCommitted()) {
request.setAttribute(
getAccessTokensRequestAttribute(),
new ArrayList<OAuthConsumerToken>(
accessTokens.values()));
chain.doFilter(request, response);
} else {
// dang. what do we do now?
throw new IllegalStateException(
"Unable to reprocess filter chain with needed OAuth2 resources because the response is already committed.");
}
} catch (Exception e1) {
resourceThatNeedsAuthorization = checkForResourceThatNeedsAuthorization(e1);
neededResourceId = resourceThatNeedsAuthorization
.getId();
}
}
} catch (OAuthRequestFailedException eo) {
fail(request, response, eo);
} catch (Exception ex) {
Throwable[] causeChain = getThrowableAnalyzer()
.determineCauseChain(ex);
OAuthRequestFailedException rfe = (OAuthRequestFailedException) getThrowableAnalyzer()
.getFirstThrowableOfType(
OAuthRequestFailedException.class,
causeChain);
if (rfe != null) {
fail(request, response, rfe);
} else {
// Rethrow ServletExceptions and RuntimeExceptions as-is
if (ex instanceof ServletException) {
throw (ServletException) ex;
} else if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
// Wrap other Exceptions. These are not expected to
// happen
throw new RuntimeException(ex);
}
}
}
} finally {
OAuthSecurityContextHolder.setContext(null);
HashMap<String, OAuthConsumerToken> tokensToRemember = new HashMap<String, OAuthConsumerToken>();
tokensToRemember.putAll(requestTokens);
tokensToRemember.putAll(accessTokens);
getRememberMeServices().rememberTokens(tokensToRemember, request,
response);
}
}
}
@@ -1,16 +0,0 @@
package org.mifosng.oauth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth.consumer.ProtectedResourceDetailsService;
import org.springframework.security.oauth.consumer.client.OAuthRestTemplate;
import org.springframework.stereotype.Service;
@Service(value="oauthRestServiceTemplate")
public class MifosNgOauthRestTemplate extends OAuthRestTemplate {
@Autowired
public MifosNgOauthRestTemplate(ProtectedResourceDetailsService protectedResourceDetailsService) {
super(protectedResourceDetailsService.loadProtectedResourceDetailsById("protectedMifosNgServices"));
}
}
@@ -1,69 +0,0 @@
package org.mifosng.oauth;
import java.util.HashMap;
import java.util.Map;
import org.mifosng.configuration.ApplicationConfigurationService;
import org.mifosng.configuration.OAuthProviderDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth.common.signature.SharedConsumerSecret;
import org.springframework.security.oauth.consumer.BaseProtectedResourceDetails;
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
import org.springframework.security.oauth.consumer.ProtectedResourceDetailsService;
import org.springframework.stereotype.Service;
@Service(value="mifosNgInMemoryResourceDetailsService")
public class MifosNgProtectedResourceDetailsService implements
ProtectedResourceDetailsService, RefreshableProtectedResourceDetailsService {
private Map<String, ProtectedResourceDetails> resourceDetailsStore = new HashMap<String, ProtectedResourceDetails>();
private final ApplicationConfigurationService applicationConfigurationService;
@Autowired
public MifosNgProtectedResourceDetailsService(ApplicationConfigurationService applicationConfigurationService) {
this.applicationConfigurationService = applicationConfigurationService;
addHardcodedMifosNgResourceIdToStore();
}
private void addHardcodedMifosNgResourceIdToStore() {
BaseProtectedResourceDetails individualLendingResourceDetails = new BaseProtectedResourceDetails();
individualLendingResourceDetails.setId("protectedMifosNgServices");
OAuthProviderDetails oauthProviderDetails = applicationConfigurationService
.retrieveOAuthProviderDetails();
individualLendingResourceDetails
.setRequestTokenURL(oauthProviderDetails.getRequestTokenUrl());
individualLendingResourceDetails
.setUserAuthorizationURL(oauthProviderDetails
.getUserAuthorizationUrl());
individualLendingResourceDetails.setAccessTokenURL(oauthProviderDetails
.getAccessTokenUrl());
individualLendingResourceDetails.setConsumerKey(oauthProviderDetails
.getConsumerkey());
individualLendingResourceDetails
.setSharedSecret(new SharedConsumerSecret(oauthProviderDetails
.getSharedSecret()));
resourceDetailsStore.put(
individualLendingResourceDetails.getId(),
individualLendingResourceDetails);
}
@Override
public ProtectedResourceDetails loadProtectedResourceDetailsById(
final String id) throws IllegalArgumentException {
return resourceDetailsStore.get(id);
}
@Override
public void refresh() {
resourceDetailsStore.clear();
addHardcodedMifosNgResourceIdToStore();
}
public ApplicationConfigurationService getApplicationConfigurationService() {
return applicationConfigurationService;
}
}
@@ -1,45 +0,0 @@
package org.mifosng.oauth;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntPathRequestMatcher;
import org.springframework.security.web.util.RequestMatcher;
public class OAuthConsumerFilterFilterInvocationSecurityMetadataSource
implements FilterInvocationSecurityMetadataSource {
private final FilterInvocationSecurityMetadataSource metadataSource;
public OAuthConsumerFilterFilterInvocationSecurityMetadataSource() {
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>();
RequestMatcher key = new AntPathRequestMatcher("/sparklr/**");
Collection<ConfigAttribute> value = new ArrayList<ConfigAttribute>();
value.add(new SecurityConfig("sparklrPhotos"));
requestMap.put(key, value);
this.metadataSource = new DefaultFilterInvocationSecurityMetadataSource(
requestMap);
}
@Override
public Collection<ConfigAttribute> getAttributes(final Object object)
throws IllegalArgumentException {
return this.metadataSource.getAttributes(object);
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return this.metadataSource.getAllConfigAttributes();
}
@Override
public boolean supports(final Class<?> clazz) {
return this.metadataSource.supports(clazz);
}
}
@@ -1,91 +0,0 @@
package org.mifosng.oauth;
import java.net.URI;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mifosng.configuration.OAuthProviderDetails;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth.consumer.OAuthConsumerToken;
import org.springframework.security.oauth.consumer.OAuthSecurityContextHolder;
import org.springframework.security.oauth.consumer.OAuthSecurityContextImpl;
import org.springframework.security.oauth.consumer.rememberme.OAuthRememberMeServices;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
/**
* Logout Filter process before oauth filters are applied so need create OAuthSercurityContext and populate with 'remembered tokens' first.
*/
public class OAuthLogoutHandler implements LogoutHandler {
private final SecurityContextLogoutHandler delegate;
private final MifosNgProtectedResourceDetailsService protectedResourceDetailsService;
private final OAuthRememberMeServices oAuthRememberMeServices;
public OAuthLogoutHandler(final SecurityContextLogoutHandler delegate, final MifosNgProtectedResourceDetailsService protectedResourceDetailsService,
final OAuthRememberMeServices oAuthRememberMeServices) {
this.delegate = delegate;
this.protectedResourceDetailsService = protectedResourceDetailsService;
this.oAuthRememberMeServices = oAuthRememberMeServices;
}
@Override
public void logout(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) {
this.delegate.logout(request, response, authentication);
OAuthSecurityContextImpl context = new OAuthSecurityContextImpl();
context.setDetails(request);
Map<String, OAuthConsumerToken> rememberedTokens = this.oAuthRememberMeServices.loadRememberedTokens(request, response);
Map<String, OAuthConsumerToken> accessTokens = new TreeMap<String, OAuthConsumerToken>();
if (rememberedTokens != null) {
for (Map.Entry<String, OAuthConsumerToken> tokenEntry : rememberedTokens.entrySet()) {
OAuthConsumerToken token = tokenEntry.getValue();
if (token != null) {
if (token.isAccessToken()) {
accessTokens.put(tokenEntry.getKey(), token);
}
}
}
}
context.setAccessTokens(accessTokens);
OAuthSecurityContextHolder.setContext(context);
if (!accessTokens.isEmpty()) {
MifosNgOauthRestTemplate oauthRestTemplate = new MifosNgOauthRestTemplate(
protectedResourceDetailsService);
OAuthProviderDetails providerDetails = this.protectedResourceDetailsService
.getApplicationConfigurationService()
.retrieveOAuthProviderDetails();
URI restUri = URI.create(providerDetails.getProviderBaseUrl()
.concat("api/protected/user/signout"));
oauthRestTemplate.exchange(restUri, HttpMethod.GET, emptyRequest(),
null);
}
OAuthSecurityContextHolder.setContext(null);
}
private HttpEntity<Object> emptyRequest() {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Accept", "application/xml");
requestHeaders.set("Content-Type", "application/xml");
HttpEntity<Object> requestEntity = new HttpEntity<Object>(
requestHeaders);
return requestEntity;
}
}
@@ -1,7 +0,0 @@
package org.mifosng.oauth;
public interface RefreshableProtectedResourceDetailsService {
void refresh();
}
@@ -1,10 +0,0 @@
package org.mifosng.ui;
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
public interface CommonRestOperations {
void logout(String accessToken);
void updateProtectedResource(ProtectedResourceDetails loadProtectedResourceDetailsById);
}
@@ -1,57 +0,0 @@
package org.mifosng.ui;
import java.net.URI;
import org.mifosng.configuration.ApplicationConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
import org.springframework.security.oauth.consumer.client.OAuthRestTemplate;
import org.springframework.stereotype.Service;
@Service(value = "commonRestOperations")
public class CommonRestOperationsImpl implements CommonRestOperations {
private OAuthRestTemplate oauthRestServiceTemplate;
private final ApplicationConfigurationService applicationConfigurationService;
@Autowired
public CommonRestOperationsImpl(
final OAuthRestTemplate oauthRestServiceTemplate,
final ApplicationConfigurationService applicationConfigurationService) {
this.oauthRestServiceTemplate = oauthRestServiceTemplate;
this.applicationConfigurationService = applicationConfigurationService;
}
private String getBaseServerUrl() {
return this.applicationConfigurationService
.retrieveOAuthProviderDetails().getProviderBaseUrl();
}
@Override
public void logout(String accessToken) {
URI restUri = URI.create(getBaseServerUrl()
.concat("api/protected/user/").concat(accessToken)
.concat("/signout"));
oauthRestServiceTemplate.exchange(restUri, HttpMethod.GET,
emptyRequest(), null);
}
@Override
public void updateProtectedResource(ProtectedResourceDetails resource) {
this.oauthRestServiceTemplate = new OAuthRestTemplate(resource);
}
private HttpEntity<Object> emptyRequest() {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Accept", "application/xml");
requestHeaders.set("Content-Type", "application/xml");
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestHeaders);
return requestEntity;
}
}
@@ -1,12 +1,6 @@
package org.mifosng.ui.admin;
import java.security.Principal;
import org.mifosng.oauth.ConsumerUserDetails;
import org.mifosng.ui.reporting.ReportingRestOperations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -22,23 +16,10 @@ import org.springframework.web.servlet.ModelAndView;
@Controller
public class ApplicationPagesRoutesController {
private final ReportingRestOperations reportingRestOperations;
@Autowired
public ApplicationPagesRoutesController(final ReportingRestOperations reportingRestOperations) {
this.reportingRestOperations = reportingRestOperations;
}
@ExceptionHandler(AccessDeniedException.class)
public String accessDeniedException() {
return "unAuthorizedAction";
}
@RequestMapping(value="/forceOAuth", method = RequestMethod.GET)
public String forceOAuth() {
this.reportingRestOperations.hackToForceAuthentication();
return "redirect:/home";
}
@RequestMapping(value="/", method = RequestMethod.GET)
public String redirectToIndexPage() {
@@ -77,13 +58,13 @@ public class ApplicationPagesRoutesController {
}
@RequestMapping(value = "/portfolio/client/{clientId}/loan/new", method = RequestMethod.GET)
public String loadLoanCreationWorkflow(final Model model, @PathVariable("clientId") final Long clientId, final Principal principal) {
public String loadLoanCreationWorkflow(final Model model, @PathVariable("clientId") final Long clientId) {
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) principal;
ConsumerUserDetails user = (ConsumerUserDetails) authenticationToken.getPrincipal();
if (user.hasNoAuthorityToSumitLoanApplication()) {
throw new AccessDeniedException("");
}
// UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) principal;
// ConsumerUserDetails user = (ConsumerUserDetails) authenticationToken.getPrincipal();
// if (user.hasNoAuthorityToSumitLoanApplication()) {
// throw new AccessDeniedException("");
// }
model.addAttribute("clientId", clientId);
@@ -1,70 +0,0 @@
package org.mifosng.ui.configuration;
import org.mifosng.configuration.ApplicationConfigurationService;
import org.mifosng.configuration.OAuthProviderDetails;
import org.mifosng.oauth.RefreshableProtectedResourceDetailsService;
import org.mifosng.ui.CommonRestOperations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.oauth.consumer.ProtectedResourceDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
@SessionAttributes({"oauthSettingsFormBean"})
@Controller
public class ConfigurationController {
private final ApplicationConfigurationService applicationConfigurationService;
private final RefreshableProtectedResourceDetailsService refreshableProtectedResourceDetailsService;
private final CommonRestOperations commonRestOperations;
@Autowired
public ConfigurationController(
final CommonRestOperations commonRestOperations, final ApplicationConfigurationService applicationConfigurationService,
final RefreshableProtectedResourceDetailsService refreshableProtectedResourceDetailsService) {
this.commonRestOperations = commonRestOperations;
this.applicationConfigurationService = applicationConfigurationService;
this.refreshableProtectedResourceDetailsService = refreshableProtectedResourceDetailsService;
}
@ExceptionHandler(AccessDeniedException.class)
public String accessDeniedException() {
return "unAuthorizedAction";
}
@ModelAttribute("oauthSettingsFormBean")
@RequestMapping(value = "oauth/configuration/edit", method = RequestMethod.GET)
public ModelAndView showOAuthConfiguration() {
OAuthProviderDetails details = this.applicationConfigurationService.retrieveOAuthProviderDetails();
OauthSettingsFormBean oauthSettingsFormBean = new OauthSettingsFormBean();
oauthSettingsFormBean.setConsumerkey(details.getConsumerkey());
oauthSettingsFormBean.setSharedSecret(details.getSharedSecret());
oauthSettingsFormBean.setOauthProviderUrl(details.getProviderBaseUrl());
return new ModelAndView("configuration/oauthconfig",
"oauthSettingsFormBean", oauthSettingsFormBean);
}
@RequestMapping(value = "oauth/configuration/edit", method = RequestMethod.POST)
public ModelAndView updateOAuthConfiguration(@ModelAttribute final OauthSettingsFormBean oauthSettingsFormBean) {
ModelAndView mav = new ModelAndView("redirect:/");
OAuthProviderDetails newDetails = new OAuthProviderDetails(oauthSettingsFormBean.getOauthProviderUrl(), oauthSettingsFormBean.getConsumerkey(), oauthSettingsFormBean.getSharedSecret());
this.applicationConfigurationService.update(newDetails);
this.refreshableProtectedResourceDetailsService.refresh();
this.commonRestOperations.updateProtectedResource(((ProtectedResourceDetailsService)refreshableProtectedResourceDetailsService).loadProtectedResourceDetailsById("protectedMifosNgServices"));
return mav;
}
}
@@ -1,32 +0,0 @@
package org.mifosng.ui.configuration;
public class OauthSettingsFormBean {
private String oauthProviderUrl;
private String sharedSecret;
private String consumerkey;
public String getOauthProviderUrl() {
return oauthProviderUrl;
}
public void setOauthProviderUrl(String oauthProviderUrl) {
this.oauthProviderUrl = oauthProviderUrl;
}
public String getSharedSecret() {
return sharedSecret;
}
public void setSharedSecret(String sharedSecret) {
this.sharedSecret = sharedSecret;
}
public String getConsumerkey() {
return consumerkey;
}
public void setConsumerkey(String consumerkey) {
this.consumerkey = consumerkey;
}
}
@@ -1,64 +0,0 @@
package org.mifosng.ui.home;
import java.util.Map;
import org.mifosng.configuration.ApplicationConfigurationService;
import org.mifosng.ui.CommonRestOperations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth.consumer.OAuthConsumerToken;
import org.springframework.security.oauth.consumer.OAuthSecurityContext;
import org.springframework.security.oauth.consumer.OAuthSecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class LogoutController {
private final CommonRestOperations commonRestOperations;
// private final ApplicationConfigurationService applicationConfigurationService;
@Autowired
public LogoutController(final CommonRestOperations commonRestOperations,
ApplicationConfigurationService applicationConfigurationService) {
this.commonRestOperations = commonRestOperations;
// this.applicationConfigurationService = applicationConfigurationService;
}
@RequestMapping(value="/logoutcontroller", method = RequestMethod.GET)
public String forceOAuth() {
// OAuthProviderDetails oauthDetails = this.applicationConfigurationService
// .retrieveOAuthProviderDetails();
String resourceId = "protectedMifosNgServices";
OAuthSecurityContext context = OAuthSecurityContextHolder.getContext();
if (context == null) {
throw new IllegalStateException(
"No OAuth security context has been established. Unable to access resource '"
+ resourceId + "'.");
}
Map<String, OAuthConsumerToken> accessTokens = context
.getAccessTokens();
OAuthConsumerToken accessToken = accessTokens == null ? null
: accessTokens.get(resourceId);
// model.addAttribute("baseUrl", oauthDetails.getProviderBaseUrl());
// model.addAttribute("consumerKey", oauthDetails.getConsumerkey());
// model.addAttribute("consumerSecret", oauthDetails.getSharedSecret());
// if (accessToken != null) {
// model.addAttribute("accessToken", accessToken.getValue());
// model.addAttribute("tokenSecret", accessToken.getSecret());
// }
String oauthToken = "";
if (accessToken != null) {
oauthToken = accessToken.getValue();
}
this.commonRestOperations.logout(oauthToken);
return "redirect:/j_spring_security_logout";
}
}
@@ -1,57 +0,0 @@
package org.mifosng.ui.migration;
import java.net.URI;
import org.mifosng.configuration.ApplicationConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth.consumer.client.OAuthRestTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class MigrationTriggerController {
private final OAuthRestTemplate oauthRestServiceTemplate;
private final ApplicationConfigurationService applicationConfigurationService;
@Autowired
public MigrationTriggerController(final OAuthRestTemplate oauthRestServiceTemplate, ApplicationConfigurationService applicationConfigurationService) {
this.oauthRestServiceTemplate = oauthRestServiceTemplate;
this.applicationConfigurationService = applicationConfigurationService;
}
@RequestMapping(value = "/migration/trigger/clients/creocore", method = RequestMethod.GET)
public String migrateClientInformation() {
URI restUri = URI
.create(getBaseServerUrl().concat("api/protected/import/trigger/clients/creocore"));
this.oauthRestServiceTemplate.getForEntity(restUri, null);
return "redirect:/home";
}
@RequestMapping(value = "/migration/trigger/loans/creocore", method = RequestMethod.GET)
public String migrateLoanInformation() {
URI restUri = URI
.create(getBaseServerUrl().concat("api/protected/import/trigger/loans/creocore"));
this.oauthRestServiceTemplate.getForEntity(restUri, null);
return "redirect:/home";
}
@RequestMapping(value = "/migration/trigger/repayments/creocore", method = RequestMethod.GET)
public String migrateLoanRepaymentsInformation() {
URI restUri = URI
.create(getBaseServerUrl().concat("api/protected/import/trigger/repayments/creocore"));
this.oauthRestServiceTemplate.getForEntity(restUri, null);
return "redirect:/home";
}
private String getBaseServerUrl() {
return this.applicationConfigurationService.retrieveOAuthProviderDetails().getProviderBaseUrl();
}
}
@@ -1,17 +1,9 @@
package org.mifosng.ui.reporting;
import java.security.Principal;
import java.util.Map;
import org.mifosng.configuration.ApplicationConfigurationService;
import org.mifosng.configuration.OAuthProviderDetails;
import org.mifosng.oauth.ConsumerUserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.oauth.consumer.OAuthConsumerToken;
import org.springframework.security.oauth.consumer.OAuthSecurityContext;
import org.springframework.security.oauth.consumer.OAuthSecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -22,51 +14,30 @@ import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/reporting")
public class ReportingController {
private final ReportingRestOperations reportingRestOperations;
private final ApplicationConfigurationService applicationConfigurationService;
@Autowired
public ReportingController(final ReportingRestOperations reportingRestOperations,
public ReportingController(
ApplicationConfigurationService applicationConfigurationService) {
this.reportingRestOperations = reportingRestOperations;
this.applicationConfigurationService = applicationConfigurationService;
}
@RequestMapping(value = "/flexireport", method = RequestMethod.GET)
public String viewFlexibleReportingPage(final Model model, final Principal principal) {
public String viewFlexibleReportingPage(final Model model) {
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) principal;
ConsumerUserDetails user = (ConsumerUserDetails) authenticationToken.getPrincipal();
if (user.hasNoReportingAuthority()) {
throw new AccessDeniedException("");
}
this.reportingRestOperations.hackToForceAuthentication();
// UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) principal;
// ConsumerUserDetails user = (ConsumerUserDetails) authenticationToken.getPrincipal();
// if (user.hasNoReportingAuthority()) {
// throw new AccessDeniedException("");
// }
OAuthProviderDetails oauthDetails = this.applicationConfigurationService
.retrieveOAuthProviderDetails();
String resourceId = "protectedMifosNgServices";
OAuthSecurityContext context = OAuthSecurityContextHolder.getContext();
if (context == null) {
throw new IllegalStateException(
"No OAuth security context has been established. Unable to access resource '"
+ resourceId + "'.");
}
Map<String, OAuthConsumerToken> accessTokens = context
.getAccessTokens();
OAuthConsumerToken accessToken = accessTokens == null ? null
: accessTokens.get(resourceId);
model.addAttribute("baseUrl", oauthDetails.getProviderBaseUrl());
model.addAttribute("consumerKey", oauthDetails.getConsumerkey());
model.addAttribute("consumerSecret", oauthDetails.getSharedSecret());
if (accessToken != null) {
model.addAttribute("accessToken", accessToken.getValue());
model.addAttribute("tokenSecret", accessToken.getSecret());
}
// model.addAttribute("consumerKey", oauthDetails.getConsumerkey());
// model.addAttribute("consumerSecret", oauthDetails.getSharedSecret());
//
return "reports/flexireport";
}
@@ -1,7 +0,0 @@
package org.mifosng.ui.reporting;
public interface ReportingRestOperations {
void hackToForceAuthentication();
}
@@ -1,53 +0,0 @@
package org.mifosng.ui.reporting;
import java.net.URI;
import org.mifosng.configuration.ApplicationConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.security.oauth.consumer.client.OAuthRestTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpStatusCodeException;
@Service
public class ReportingRestOperationsImpl implements ReportingRestOperations {
private final OAuthRestTemplate oauthRestServiceTemplate;
private final ApplicationConfigurationService applicationConfigurationService;
@Autowired
public ReportingRestOperationsImpl(
final OAuthRestTemplate oauthRestServiceTemplate, final ApplicationConfigurationService applicationConfigurationService) {
this.oauthRestServiceTemplate = oauthRestServiceTemplate;
this.applicationConfigurationService = applicationConfigurationService;
}
private HttpEntity<Object> emptyRequest() {
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("Accept", "application/xml");
requestHeaders.set("Content-Type", "application/xml");
HttpEntity<Object> requestEntity = new HttpEntity<Object>(
requestHeaders);
return requestEntity;
}
private String getBaseServerUrl() {
return this.applicationConfigurationService.retrieveOAuthProviderDetails().getProviderBaseUrl();
}
@Override
public void hackToForceAuthentication() {
try {
URI restUri = URI
.create(getBaseServerUrl().concat("api/v1/reports/forceauth"));
this.oauthRestServiceTemplate.exchange(restUri, HttpMethod.GET, emptyRequest(), null);
} catch (HttpStatusCodeException e) {
System.err.println(e.getMessage());
throw e;
}
}
}
+3 -2
View File
@@ -80,8 +80,9 @@ dependencies {
[group: 'org.springframework', name: 'spring-aspects', version: springVersion],
[group: 'org.springframework', name: 'spring-web', version: springVersion],
[group: 'org.springframework', name: 'spring-webmvc', version: springVersion],
[group: 'org.springframework.webflow', name: 'spring-webflow', version: '2.3.0.RELEASE'],
[group: 'org.springframework.security.oauth', name: 'spring-security-oauth', version: springSecurityOauthVersion],
[group: 'org.springframework.security', name: 'spring-security-core', version: springSecurityVersion],
[group: 'org.springframework.security', name: 'spring-security-web', version: springSecurityVersion],
[group: 'org.springframework.security', name: 'spring-security-config', version: springSecurityVersion],
[group: 'org.springframework.security', name: 'spring-security-taglibs', version: springSecurityVersion],
[group: 'org.aspectj', name: 'aspectjrt', version: '1.6.11.RELEASE'],
@@ -1,15 +0,0 @@
package org.mifosng.oauth;
import org.springframework.security.oauth.provider.token.OAuthProviderToken;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenServices;
/**
* This is just a temporary hack, should pass oauth access token, access secret, consumer key, consumer secret to get access to authenticated user permissions
*/
public interface CustomOAuthProviderTokenServices extends OAuthProviderTokenServices {
OAuthProviderToken getTokenByNonEncodedKey(String oauthToken);
void removeTokenByNonEncodedKey(String oauthToken);
}
@@ -1,155 +0,0 @@
package org.mifosng.oauth;
import java.io.IOException;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth.common.OAuthConsumerParameter;
import org.springframework.security.oauth.common.OAuthException;
import org.springframework.security.oauth.common.signature.OAuthSignatureMethod;
import org.springframework.security.oauth.common.signature.SignatureSecret;
import org.springframework.security.oauth.common.signature.UnsupportedSignatureMethodException;
import org.springframework.security.oauth.provider.ConsumerAuthentication;
import org.springframework.security.oauth.provider.ConsumerCredentials;
import org.springframework.security.oauth.provider.ConsumerDetails;
import org.springframework.security.oauth.provider.InvalidOAuthParametersException;
import org.springframework.security.oauth.provider.filter.ProtectedResourceProcessingFilter;
import org.springframework.security.oauth.provider.token.OAuthProviderToken;
public class CustomProtectedResourceProcessingFilter extends
ProtectedResourceProcessingFilter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (!skipProcessing(request)) {
if (requiresAuthentication(request, response, chain)) {
if (!allowMethod(request.getMethod().toUpperCase())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
try {
Map<String, String> oauthParams = getProviderSupport().parseParameters(request);
if (parametersAreAdequate(oauthParams)) {
String consumerKey = oauthParams.get(OAuthConsumerParameter.oauth_consumer_key.toString());
if (consumerKey == null) {
throw new InvalidOAuthParametersException(messages.getMessage("OAuthProcessingFilter.missingConsumerKey", "Missing consumer key."));
}
//load the consumer details.
ConsumerDetails consumerDetails = getConsumerDetailsService().loadConsumerByConsumerKey(consumerKey);
//validate the parameters for the consumer.
validateOAuthParams(consumerDetails, oauthParams);
//extract the credentials.
String token = oauthParams.get(OAuthConsumerParameter.oauth_token.toString());
String signatureMethod = oauthParams.get(OAuthConsumerParameter.oauth_signature_method.toString());
String signature = oauthParams.get(OAuthConsumerParameter.oauth_signature.toString());
String signatureBaseString = getProviderSupport().getSignatureBaseString(request);
ConsumerCredentials credentials = new ConsumerCredentials(consumerKey, signature, signatureMethod, signatureBaseString, token);
//create an authentication request.
ConsumerAuthentication authentication = new ConsumerAuthentication(consumerDetails, credentials, oauthParams);
authentication.setDetails(createDetails(request, consumerDetails));
Authentication previousAuthentication = SecurityContextHolder.getContext().getAuthentication();
try {
//set the authentication request (unauthenticated) into the context.
SecurityContextHolder.getContext().setAuthentication(authentication);
//validate the signature.
if (token == null) {
validateSignature(authentication);
} else {
if (!"OPTIONS".equalsIgnoreCase(request.getMethod().toUpperCase())) {
validateSignature(authentication);
}
}
//mark the authentication request as validated.
authentication.setSignatureValidated(true);
//mark that processing has been handled.
request.setAttribute(OAUTH_PROCESSING_HANDLED, Boolean.TRUE);
//go.
onValidSignature(request, response, chain);
}
finally {
//clear out the consumer authentication to make sure it doesn't get cached.
resetPreviousAuthentication(previousAuthentication);
}
}
else if (!isIgnoreInadequateCredentials()) {
throw new InvalidOAuthParametersException(messages.getMessage("OAuthProcessingFilter.missingCredentials", "Inadequate OAuth consumer credentials."));
}
else {
chain.doFilter(request, response);
}
}
catch (AuthenticationException ae) {
fail(request, response, ae);
}
catch (ServletException e) {
if (e.getRootCause() instanceof AuthenticationException) {
fail(request, response, (AuthenticationException) e.getRootCause());
}
else {
throw e;
}
}
}
else {
chain.doFilter(servletRequest, servletResponse);
}
}
else {
chain.doFilter(servletRequest, servletResponse);
}
}
@Override
protected void validateSignature(ConsumerAuthentication authentication)
throws AuthenticationException {
SignatureSecret secret = authentication.getConsumerDetails()
.getSignatureSecret();
String token = authentication.getConsumerCredentials().getToken();
OAuthProviderToken authToken = null;
if (token != null && !"".equals(token)) {
authToken = getTokenServices().getToken(token);
}
String signatureMethod = authentication.getConsumerCredentials()
.getSignatureMethod();
OAuthSignatureMethod method;
try {
method = getSignatureMethodFactory().getSignatureMethod(
signatureMethod, secret,
authToken != null ? authToken.getSecret() : null);
} catch (UnsupportedSignatureMethodException e) {
throw new OAuthException(e.getMessage(), e);
}
String signatureBaseString = authentication.getConsumerCredentials()
.getSignatureBaseString();
String signature = authentication.getConsumerCredentials()
.getSignature();
method.verify(signatureBaseString, signature);
}
}
@@ -1,63 +0,0 @@
package org.mifosng.oauth;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth.provider.token.OAuthAccessProviderToken;
import org.springframework.security.oauth.provider.token.OAuthProviderToken;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenImpl;
public class CustomTokenServices implements CustomOAuthProviderTokenServices {
private final ConcurrentHashMap<String, OAuthProviderTokenImpl> requestTokenStore = new ConcurrentHashMap<String, OAuthProviderTokenImpl>();
private final RemovableInMemoryProviderTokenServices delegate;
public CustomTokenServices(RemovableInMemoryProviderTokenServices delegate) {
this.delegate = delegate;
}
@Override
public OAuthProviderToken getToken(String token)
throws AuthenticationException {
return this.delegate.getToken(token);
}
@Override
public OAuthProviderToken createUnauthorizedRequestToken(
String consumerKey, String callbackUrl)
throws AuthenticationException {
return this.delegate.createUnauthorizedRequestToken(consumerKey, callbackUrl);
}
@Override
public void authorizeRequestToken(String requestToken, String verifier,
Authentication authentication) throws AuthenticationException {
this.delegate.authorizeRequestToken(requestToken, verifier, authentication);
}
@Override
public OAuthAccessProviderToken createAccessToken(String requestToken)
throws AuthenticationException {
OAuthProviderTokenImpl accessToken = (OAuthProviderTokenImpl)this.delegate.createAccessToken(requestToken);
this.requestTokenStore.put(requestToken, accessToken);
return accessToken;
}
@Override
public OAuthProviderToken getTokenByNonEncodedKey(String oauthToken) {
return this.requestTokenStore.get(oauthToken);
}
@Override
public void removeTokenByNonEncodedKey(String oauthToken) {
OAuthProviderTokenImpl accessToken = this.requestTokenStore.remove(oauthToken);
if (accessToken != null) {
String acccesTokenValue = accessToken.getValue();
this.delegate.removeAccessToken(acccesTokenValue);
} else {
this.delegate.removeAccessToken(oauthToken);
}
}
}
@@ -1,44 +0,0 @@
package org.mifosng.oauth;
import java.util.HashMap;
import java.util.Map;
import org.mifosng.platform.oauthconsumer.domain.OauthConsumerDetail;
import org.mifosng.platform.oauthconsumer.domain.OauthConsumerDetailRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth.common.OAuthException;
import org.springframework.security.oauth.provider.ConsumerDetails;
import org.springframework.security.oauth.provider.ConsumerDetailsService;
import org.springframework.security.oauth.provider.InvalidOAuthParametersException;
public class MifosNgConsumerDetailsService implements ConsumerDetailsService {
private Map<String, ConsumerDetails> consumerDetailsStore = new HashMap<String, ConsumerDetails>();
@Autowired
private OauthConsumerDetailRepository oauthConsumerDetailRepository;
/**
* consumer service is used for by spring security oauth for all requests so makes sense to store consumer details in memory
* rather than query the database based on each request.
*/
@Override
public ConsumerDetails loadConsumerByConsumerKey(final String consumerKey)
throws OAuthException {
ConsumerDetails detailsFromInMemoryStore = consumerDetailsStore.get(consumerKey);
OauthConsumerDetail detailsFromDatabase = null;
if (detailsFromInMemoryStore == null) {
detailsFromDatabase = this.oauthConsumerDetailRepository.findByConsumerKey(consumerKey);
}
ConsumerDetails consumerDetails = detailsFromInMemoryStore != null ? detailsFromInMemoryStore : detailsFromDatabase;
if (consumerDetails == null) {
throw new InvalidOAuthParametersException("Consumer not found: " + consumerKey);
} else {
consumerDetailsStore.put(consumerKey, detailsFromDatabase);
}
return consumerDetails;
}
}
@@ -1,82 +0,0 @@
package org.mifosng.oauth;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth.common.OAuthConsumerParameter;
import org.springframework.security.oauth.provider.OAuthProviderSupport;
import org.springframework.security.oauth.provider.filter.CoreOAuthProviderSupport;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenImpl;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenServices;
import org.springframework.web.filter.GenericFilterBean;
public class OAuthParametersAwareSecurityContextPerRequestFilter extends
GenericFilterBean {
private OAuthProviderSupport providerSupport = new CoreOAuthProviderSupport();
private final OAuthProviderTokenServices tokenServices;
public OAuthParametersAwareSecurityContextPerRequestFilter(OAuthProviderTokenServices tokenServices) {
this.tokenServices = tokenServices;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
Map<String, String> oauthParams = this.providerSupport.parseParameters(request);
String anonymousUserHash = "" + "anonymousUser".hashCode();
Collection<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("ROLE_ANONYMOUS"));
Authentication authentication = new AnonymousAuthenticationToken(anonymousUserHash, "anonymousUser", authorities);
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(authentication);
if (oauthTokenExists(oauthParams)) {
String oauthToken = retrieveOAuthToken(oauthParams);
OAuthProviderTokenImpl token = (OAuthProviderTokenImpl) this.tokenServices.getToken(oauthToken);
if (token.getUserAuthentication() != null) {
context.setAuthentication(token.getUserAuthentication());
}
} else {
String requestToken = request.getParameter("requestToken");
if (StringUtils.isNotBlank(requestToken)) {
OAuthProviderTokenImpl token = (OAuthProviderTokenImpl) this.tokenServices.getToken(requestToken);
if (token.getUserAuthentication() != null) {
context.setAuthentication(token.getUserAuthentication());
}
}
}
chain.doFilter(request, response);
}
private String retrieveOAuthToken(Map<String, String> oauthParams) {
return oauthParams.get(OAuthConsumerParameter.oauth_token.toString());
}
private boolean oauthTokenExists(Map<String, String> oauthParams) {
return oauthParams.containsKey(OAuthConsumerParameter.oauth_token.toString());
}
}
@@ -1,11 +0,0 @@
package org.mifosng.oauth;
import org.springframework.security.oauth.provider.token.InMemoryProviderTokenServices;
public class RemovableInMemoryProviderTokenServices extends
InMemoryProviderTokenServices {
public void removeAccessToken(String acccesTokenValue) {
super.removeToken(acccesTokenValue);
}
}
@@ -40,8 +40,7 @@ import org.springframework.stereotype.Component;
@Scope("singleton")
public class AdditionalFieldsApiResource {
private final static Logger logger = LoggerFactory
.getLogger(AdditionalFieldsApiResource.class);
private final static Logger logger = LoggerFactory.getLogger(AdditionalFieldsApiResource.class);
@Autowired
private ReadExtraDataAndReportingService readExtraDataAndReportingService;
@@ -24,14 +24,8 @@ import org.mifosng.data.command.NoteCommand;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.client.service.ClientReadPlatformService;
import org.mifosng.platform.client.service.ClientWritePlatformService;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Path("/v1/clients")
@@ -48,24 +42,11 @@ public class ClientApiResource {
@Autowired
private ApiDataConversionService apiDataConversionService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveAllIndividualClients() {
hardcodeUserIntoSecurityContext();
Collection<ClientData> clients = this.clientReadPlatformService.retrieveAllIndividualClients();
return Response.ok().entity(new ClientList(clients)).build();
@@ -77,8 +58,6 @@ public class ClientApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveClientData(@PathParam("clientId") final Long clientId) {
hardcodeUserIntoSecurityContext();
ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId);
return Response.ok().entity(clientData).build();
@@ -90,8 +69,6 @@ public class ClientApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response newClientDetails() {
hardcodeUserIntoSecurityContext();
ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails();
return Response.ok().entity(clientData).build();
@@ -102,8 +79,6 @@ public class ClientApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public Response enrollClient(final EnrollClientCommand command) {
hardcodeUserIntoSecurityContext();
LocalDate joiningDate = apiDataConversionService.convertFrom(command.getJoiningDateFormatted(), "joiningDateFormatted", command.getDateFormat());
command.setJoiningDate(joiningDate);
@@ -119,8 +94,6 @@ public class ClientApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public Response retrieveClientAccount(@PathParam("clientId") final Long clientId) {
hardcodeUserIntoSecurityContext();
ClientLoanAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId);
return Response.ok().entity(clientAccount).build();
@@ -132,8 +105,6 @@ public class ClientApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveAllClientNotes(@PathParam("clientId") final Long clientId) {
hardcodeUserIntoSecurityContext();
Collection<NoteData> notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId);
return Response.ok().entity(new NoteDataList(notes)).build();
@@ -145,8 +116,6 @@ public class ClientApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response addNewClientNote(@PathParam("clientId") final Long clientId, final NoteCommand command) {
hardcodeUserIntoSecurityContext();
command.setClientId(clientId);
EntityIdentifier identifier = this.clientWritePlatformService.addClientNote(command);
@@ -160,8 +129,6 @@ public class ClientApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public Response retrieveClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId) {
hardcodeUserIntoSecurityContext();
NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId);
return Response.ok().entity(note).build();
@@ -173,8 +140,6 @@ public class ClientApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public Response updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId, final NoteCommand command) {
hardcodeUserIntoSecurityContext();
command.setClientId(clientId);
command.setId(noteId);
@@ -1,4 +1,4 @@
package org.mifosng.platform.api.configuration;
package org.mifosng.platform.api;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -1,4 +1,4 @@
package org.mifosng.platform.api.loanproduct;
package org.mifosng.platform.api;
import java.util.Collection;
@@ -18,14 +18,8 @@ import org.mifosng.data.LoanProductList;
import org.mifosng.data.command.LoanProductCommand;
import org.mifosng.platform.loanproduct.service.LoanProductReadPlatformService;
import org.mifosng.platform.loanproduct.service.LoanProductWritePlatformService;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
/*
@@ -58,24 +52,11 @@ public class LoanProductApiResource {
@Autowired
private LoanProductWritePlatformService loanProductWritePlatformService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON})
public Response createLoanProduct(LoanProductCommand command) {
hardcodeUserIntoSecurityContext();
EntityIdentifier entityIdentifier = this.loanProductWritePlatformService.createLoanProduct(command);
return Response.ok().entity(entityIdentifier).build();
@@ -86,8 +67,6 @@ public class LoanProductApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveAllLoanProducts() {
hardcodeUserIntoSecurityContext();
Collection<LoanProductData> products = this.loanProductReadPlatformService.retrieveAllLoanProducts();
return Response.ok().entity(new LoanProductList(products)).build();
@@ -102,8 +81,6 @@ public class LoanProductApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveNewLoanProductDetails() {
hardcodeUserIntoSecurityContext();
LoanProductData loanProduct = this.loanProductReadPlatformService.retrieveNewLoanProductDetails();
return Response.ok().entity(loanProduct).build();
@@ -115,8 +92,6 @@ public class LoanProductApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveLoanProductDetails(@PathParam("productId") final Long productId) {
hardcodeUserIntoSecurityContext();
LoanProductData loanProduct = this.loanProductReadPlatformService.retrieveLoanProduct(productId);
return Response.ok().entity(loanProduct).build();
@@ -128,8 +103,6 @@ public class LoanProductApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public Response updateLoanProduct(@PathParam("productId") final Long productId, final LoanProductCommand command) {
hardcodeUserIntoSecurityContext();
command.setId(productId);
EntityIdentifier entityIdentifier = this.loanProductWritePlatformService.updateLoanProduct(command);
@@ -33,14 +33,8 @@ import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.loan.service.CalculationPlatformService;
import org.mifosng.platform.loan.service.LoanReadPlatformService;
import org.mifosng.platform.loan.service.LoanWritePlatformService;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Path("/v1/loans")
@@ -60,25 +54,12 @@ public class LoansApiResource {
@Autowired
private ApiDataConversionService apiDataConversionService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveDetailsForNewLoanApplicationStepOne(@QueryParam("clientId") final Long clientId, @QueryParam("productId") final Long productId) {
hardcodeUserIntoSecurityContext();
NewLoanWorkflowStepOneData workflowData = this.loanReadPlatformService.retrieveClientAndProductDetails(clientId, productId);
return Response.ok().entity(workflowData).build();
@@ -90,8 +71,6 @@ public class LoansApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveLoanAccountDetails(@PathParam("loanId") final Long loanId) {
hardcodeUserIntoSecurityContext();
LoanAccountData loanAccount = this.loanReadPlatformService.retrieveLoanAccountDetails(loanId);
return Response.ok().entity(loanAccount).build();
@@ -102,8 +81,6 @@ public class LoansApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response calculateLoanSchedule(@QueryParam("command") final String commandParam, final SubmitLoanApplicationCommand command) {
hardcodeUserIntoSecurityContext();
LocalDate expectedDisbursementDate = apiDataConversionService.convertFrom(command.getExpectedDisbursementDateFormatted(), "expectedDisbursementDateFormatted", command.getDateFormat());
LocalDate repaymentsStartingFromDate = apiDataConversionService.convertFrom(command.getRepaymentsStartingFromDateFormatted(), "repaymentsStartingFromDateFormatted", command.getDateFormat());
LocalDate interestCalculatedFromDate = apiDataConversionService.convertFrom(command.getInterestCalculatedFromDateFormatted(), "interestCalculatedFromDateFormatted", command.getDateFormat());
@@ -144,8 +121,6 @@ public class LoansApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response deleteLoanApplication(@PathParam("loanId") final Long loanId) {
hardcodeUserIntoSecurityContext();
EntityIdentifier identifier = this.loanWritePlatformService.deleteLoan(loanId);
return Response.ok().entity(identifier).build();
@@ -159,8 +134,6 @@ public class LoansApiResource {
@QueryParam("command") final String commandParam,
final LoanStateTransitionCommand command) {
hardcodeUserIntoSecurityContext();
LocalDate eventDate = this.apiDataConversionService.convertFrom(command.getEventDateFormatted(), "eventDateFormatted", command.getDateFormat());
command.setLoanId(loanId);
@@ -189,8 +162,6 @@ public class LoansApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response undoStateTransitions(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam) {
hardcodeUserIntoSecurityContext();
if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("undoapproval")) {
UndoLoanApprovalCommand undoCommand = new UndoLoanApprovalCommand(loanId);
EntityIdentifier identifier = this.loanWritePlatformService.undoLoanApproval(undoCommand);
@@ -210,8 +181,6 @@ public class LoansApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response executeLoanTransaction(@PathParam("loanId") final Long loanId, @QueryParam("transactionType") final String transactionType, final LoanTransactionCommand command) {
hardcodeUserIntoSecurityContext();
command.setLoanId(loanId);
LocalDate transactionDate = apiDataConversionService.convertFrom(command.getTransactionDateFormatted(), "transactionDateFormatted", command.getDateFormat());
@@ -235,8 +204,6 @@ public class LoansApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveNewRepaymentDetails(@PathParam("loanId") final Long loanId, @QueryParam("type") final String transactionType) {
hardcodeUserIntoSecurityContext();
if (StringUtils.isNotBlank(transactionType) && transactionType.trim().equalsIgnoreCase("waiver")) {
LoanRepaymentData loanWaiverData = this.loanReadPlatformService.retrieveNewLoanWaiverDetails(loanId);
return Response.ok().entity(loanWaiverData).build();
@@ -252,8 +219,6 @@ public class LoansApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveRepaymentDetails(@PathParam("loanId") final Long loanId, @PathParam("repaymentId") final Long repaymentId) {
hardcodeUserIntoSecurityContext();
LoanRepaymentData loanRepaymentData = this.loanReadPlatformService.retrieveLoanRepaymentDetails(loanId, repaymentId);
return Response.ok().entity(loanRepaymentData).build();
@@ -265,8 +230,6 @@ public class LoansApiResource {
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response adjustLoanTransaction(@PathParam("loanId") final Long loanId, @PathParam("repaymentId") final Long repaymentId, final AdjustLoanTransactionCommand command) {
hardcodeUserIntoSecurityContext();
command.setLoanId(loanId);
command.setRepaymentId(repaymentId);
@@ -1,4 +1,4 @@
package org.mifosng.platform.api.office;
package org.mifosng.platform.api;
import java.util.Collection;
@@ -20,14 +20,8 @@ import org.mifosng.data.command.OfficeCommand;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.organisation.service.OfficeReadPlatformService;
import org.mifosng.platform.organisation.service.OfficeWritePlatformService;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Path("/v1/offices")
@@ -44,22 +38,10 @@ public class OfficeApiResource {
@Autowired
private ApiDataConversionService apiDataConversionService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveOffices() {
hardcodeUserIntoSecurityContext();
Collection<OfficeData> offices = this.readPlatformService.retrieveAllOffices();
@@ -71,9 +53,8 @@ public class OfficeApiResource {
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveOfficeTemplate() {
hardcodeUserIntoSecurityContext();
OfficeData newOfficeTemplate = this.readPlatformService.retrieveNewOfficeTemplate();
OfficeData newOfficeTemplate = this.readPlatformService.retrieveNewOfficeTemplate();
return Response.ok().entity(newOfficeTemplate).build();
}
@@ -82,7 +63,6 @@ public class OfficeApiResource {
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON})
public Response createOffice(final OfficeCommand command) {
hardcodeUserIntoSecurityContext();
LocalDate openingDate = apiDataConversionService.convertFrom(command.getOpeningDateFormatted(), "openingDateFormatted", command.getDateFormat());
command.setOpeningDate(openingDate);
@@ -97,7 +77,6 @@ public class OfficeApiResource {
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON})
public Response retreiveOffice(@PathParam("officeId") final Long officeId) {
hardcodeUserIntoSecurityContext();
OfficeData office = this.readPlatformService.retrieveOffice(officeId);
@@ -110,8 +89,6 @@ public class OfficeApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response updateOffice(@PathParam("officeId") final Long officeId, final OfficeCommand command) {
hardcodeUserIntoSecurityContext();
LocalDate openingDate = apiDataConversionService.convertFrom(command.getOpeningDateFormatted(), "openingDateFormatted", command.getDateFormat());
command.setOpeningDate(openingDate);
command.setId(officeId);
@@ -1,4 +1,4 @@
package org.mifosng.platform.api.user;
package org.mifosng.platform.api;
import java.util.Collection;
@@ -11,15 +11,9 @@ import javax.ws.rs.core.Response;
import org.mifosng.data.PermissionData;
import org.mifosng.data.PermissionList;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.mifosng.platform.user.service.PermissionReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Path("/v1/permissions")
@@ -30,23 +24,11 @@ public class PermissionApiResource {
@Autowired
private PermissionReadPlatformService permissionReadPlatformService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveAllPermissions() {
hardcodeUserIntoSecurityContext();
Collection<PermissionData> permissions = this.permissionReadPlatformService.retrieveAllPermissions();
return Response.ok().entity(new PermissionList(permissions)).build();
}
@@ -29,8 +29,7 @@ import org.springframework.stereotype.Component;
@Scope("singleton")
public class ReportingApiResource {
private final static Logger logger = LoggerFactory
.getLogger(ReportingApiResource.class);
private final static Logger logger = LoggerFactory.getLogger(ReportingApiResource.class);
@Autowired
private ReadExtraDataAndReportingService ReadExtraDataAndReportingService;
@@ -115,10 +114,4 @@ public class ReportingApiResource {
"attachment;filename=" + reportName.replaceAll(" ", "")
+ ".csv").build();
}
@GET
@Path("forceauth")
public Response hackToForceAuthentication() {
return Response.ok().build();
}
}
@@ -1,4 +1,4 @@
package org.mifosng.platform.api.user;
package org.mifosng.platform.api;
import java.util.Collection;
@@ -17,17 +17,11 @@ import org.mifosng.data.PermissionData;
import org.mifosng.data.RoleData;
import org.mifosng.data.RoleList;
import org.mifosng.data.command.RoleCommand;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.mifosng.platform.user.service.PermissionReadPlatformService;
import org.mifosng.platform.user.service.RoleReadPlatformService;
import org.mifosng.platform.user.service.RoleWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Path("/v1/roles")
@@ -44,23 +38,11 @@ public class RoleApiResource {
@Autowired
private RoleWritePlatformService roleWritePlatformService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveAllRoles() {
hardcodeUserIntoSecurityContext();
Collection<RoleData> roles = this.roleReadPlatformService.retrieveAllRoles();
return Response.ok().entity(new RoleList(roles)).build();
}
@@ -71,8 +53,6 @@ public class RoleApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveNewRoleDetails() {
hardcodeUserIntoSecurityContext();
Collection<PermissionData> allPermissions = this.permissionReadPlatformService.retrieveAllPermissions();
RoleData role = new RoleData();
@@ -85,7 +65,7 @@ public class RoleApiResource {
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response createRole(final RoleCommand command) {
hardcodeUserIntoSecurityContext();
Long roleId = this.roleWritePlatformService.createRole(command);
return Response.ok().entity(new EntityIdentifier(roleId)).build();
}
@@ -96,8 +76,6 @@ public class RoleApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveRole(@PathParam("roleId") final Long roleId) {
hardcodeUserIntoSecurityContext();
RoleData role = this.roleReadPlatformService.retrieveRole(roleId);
Collection<PermissionData> availablePermissions = this.permissionReadPlatformService.retrieveAllPermissions();
@@ -112,7 +90,6 @@ public class RoleApiResource {
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response updateRole(@PathParam("roleId") final Long roleId, final RoleCommand command) {
hardcodeUserIntoSecurityContext();
command.setId(roleId);
this.roleWritePlatformService.updateRole(command);
@@ -1,4 +1,4 @@
package org.mifosng.platform.api.user;
package org.mifosng.platform.api;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -12,16 +12,10 @@ import org.mifosng.data.AppUserData;
import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.command.ChangePasswordCommand;
import org.mifosng.data.command.UserCommand;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.mifosng.platform.user.service.AppUserReadPlatformService;
import org.mifosng.platform.user.service.AppUserWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Path("/v1/useraccounts")
@@ -35,25 +29,12 @@ public class UserAccountApiResource {
@Autowired
private AppUserWritePlatformService appUserWritePlatformService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@GET
@Path("current")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveCurrentUser() {
hardcodeUserIntoSecurityContext();
AppUserData user = this.appUserReadPlatformService.retrieveCurrentUser();
return Response.ok().entity(user).build();
@@ -65,8 +46,6 @@ public class UserAccountApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response updateCurrentUser(UserCommand command) {
hardcodeUserIntoSecurityContext();
Long userId = this.appUserWritePlatformService.updateCurrentUser(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
@@ -87,8 +66,6 @@ public class UserAccountApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response updateCurrentUserPassword(ChangePasswordCommand command) {
hardcodeUserIntoSecurityContext();
Long userId = this.appUserWritePlatformService.updateCurrentUserPassword(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
@@ -1,4 +1,4 @@
package org.mifosng.platform.api.user;
package org.mifosng.platform.api;
import java.util.Collection;
@@ -17,16 +17,10 @@ import org.mifosng.data.AppUserData;
import org.mifosng.data.EntityIdentifier;
import org.mifosng.data.UserList;
import org.mifosng.data.command.UserCommand;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.AppUserRepository;
import org.mifosng.platform.user.service.AppUserReadPlatformService;
import org.mifosng.platform.user.service.AppUserWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Path("/v1/users")
@@ -40,24 +34,11 @@ public class UserApiResource {
@Autowired
private AppUserWritePlatformService appUserWritePlatformService;
@Autowired
private AppUserRepository appUserRepository;
private void hardcodeUserIntoSecurityContext() {
AppUser currentUser = this.appUserRepository.findOne(Long.valueOf(1));
Authentication auth = new UsernamePasswordAuthenticationToken(currentUser, currentUser, currentUser.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(auth);
}
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Produces({MediaType.APPLICATION_JSON})
public Response retrieveUsers() {
hardcodeUserIntoSecurityContext();
Collection<AppUserData> users = this.appUserReadPlatformService.retrieveAllUsers();
return Response.ok().entity(new UserList(users)).build();
@@ -69,8 +50,6 @@ public class UserApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response retrieveUser(@PathParam("userId") final Long userId) {
hardcodeUserIntoSecurityContext();
AppUserData user = this.appUserReadPlatformService.retrieveUser(userId);
return Response.ok().entity(user).build();
@@ -82,7 +61,6 @@ public class UserApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response newUserDetails() {
hardcodeUserIntoSecurityContext();
AppUserData newUser = this.appUserReadPlatformService.retrieveNewUserDetails();
return Response.ok().entity(newUser).build();
@@ -93,9 +71,8 @@ public class UserApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response createUser(UserCommand command) {
hardcodeUserIntoSecurityContext();
Long userId = this.appUserWritePlatformService.createUser(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
Long userId = this.appUserWritePlatformService.createUser(command);
return Response.ok().entity(new EntityIdentifier(userId)).build();
}
@DELETE
@@ -115,8 +92,6 @@ public class UserApiResource {
@Produces({ MediaType.APPLICATION_JSON})
public Response updateUser(@PathParam("userId") final Long userId, UserCommand command) {
hardcodeUserIntoSecurityContext();
command.setId(userId);
this.appUserWritePlatformService.updateUser(command);
@@ -0,0 +1,21 @@
package org.mifosng.platform.api.infrastructure;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
@Component("apiAuthenticationEntryPoint")
public final class ApiAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public final void commence(HttpServletRequest request,
HttpServletResponse response, AuthenticationException authException)
throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthenticated");
}
}
@@ -0,0 +1,52 @@
package org.mifosng.platform.api.infrastructure;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.StringUtils;
public class ApiAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null) {
super.onAuthenticationSuccess(request, response, authentication);
return;
}
String targetUrlParameter = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl()
|| (targetUrlParameter != null && StringUtils.hasText(request
.getParameter(targetUrlParameter)))) {
requestCache.removeRequest(request, response);
super.onAuthenticationSuccess(request, response, authentication);
return;
}
clearAuthenticationAttributes(request);
// // Use the DefaultSavedRequest URL
// String targetUrl = savedRequest.getRedirectUrl();
// logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
// getRedirectStrategy().sendRedirect(request, response, targetUrl);
}
public void setRequestCache(RequestCache requestCache) {
this.requestCache = requestCache;
}
}
@@ -1,106 +0,0 @@
package org.mifosng.platform.infrastructure;
import java.security.Principal;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
import org.mifosng.data.command.UpdateUsernamePasswordCommand;
import org.mifosng.platform.WritePlatformService;
import org.mifosng.platform.user.domain.PasswordMustBeDifferentException;
import org.mifosng.platform.user.domain.UsernameMustBeDifferentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
@Controller
@SessionAttributes("firstTimeLoginFormBean")
public class FirstTimeLoginController {
@Autowired
private WritePlatformService signupPlatformService;
@ModelAttribute("firstTimeLoginFormBean")
@RequestMapping(value = "/firsttimelogin", method = RequestMethod.GET)
public FirstTimeLoginFormBean loadSignupForm(final Principal principal,
final HttpSession httpSession) {
String successView = "/index";
String savedRequestView = (String) httpSession
.getAttribute("firsttimeloginview");
if (StringUtils.isNotBlank(savedRequestView)) {
successView = savedRequestView;
}
FirstTimeLoginFormBean bean = new FirstTimeLoginFormBean();
bean.setOldUsername(principal.getName());
bean.setSuccessView(successView);
return bean;
}
@ModelAttribute("firstTimeLoginFormBean")
@RequestMapping(value = "/firsttimelogin", method = RequestMethod.POST)
public ModelAndView handleSignup(
@ModelAttribute("firstTimeLoginFormBean") final FirstTimeLoginFormBean firstTimeLoginFormBean,
final BindingResult result, final SessionStatus status) {
if (result.hasErrors()) {
return new ModelAndView("firsttimelogin", "firstTimeLoginFormBean",
firstTimeLoginFormBean);
}
try {
UpdateUsernamePasswordCommand command = new UpdateUsernamePasswordCommand(
firstTimeLoginFormBean.getOldUsername(),
firstTimeLoginFormBean.getUsername(),
firstTimeLoginFormBean.getPassword());
this.signupPlatformService
.updateUsernamePasswordOnFirstTimeLogin(command);
status.setComplete();
RedirectView redirectView = new RedirectView(
firstTimeLoginFormBean.getSuccessView());
if (!firstTimeLoginFormBean.getSuccessView().startsWith("http")) {
redirectView.setContextRelative(true);
}
return new ModelAndView(redirectView);
} catch (UsernameAlreadyExistsException e) {
ObjectError error = new ObjectError("firstTimeLoginFormBean",
new String[] { "username.already.exists" },
new Object[] { firstTimeLoginFormBean.getUsername() },
"An user with username {0} already exists.");
result.addError(error);
return new ModelAndView("firsttimelogin", "firstTimeLoginFormBean",
firstTimeLoginFormBean);
} catch (UsernameMustBeDifferentException e) {
ObjectError error = new ObjectError("firstTimeLoginFormBean",
new String[] { "new.username.must.be.different" },
new Object[] {},
"The new username cannot be the same as existing username.");
result.addError(error);
return new ModelAndView("firsttimelogin", "firstTimeLoginFormBean",
firstTimeLoginFormBean);
} catch (PasswordMustBeDifferentException e) {
ObjectError error = new ObjectError("firstTimeLoginFormBean",
new String[] { "new.password.must.be.different" },
new Object[] {},
"The new password cannot be the same as existing password.");
result.addError(error);
return new ModelAndView("firsttimelogin", "firstTimeLoginFormBean",
firstTimeLoginFormBean);
}
}
}
@@ -1,96 +0,0 @@
package org.mifosng.platform.infrastructure;
import java.io.IOException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth.common.OAuthConsumerParameter;
import org.springframework.security.oauth.provider.OAuthProviderSupport;
import org.springframework.security.oauth.provider.filter.CoreOAuthProviderSupport;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenImpl;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenServices;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
public class FirstTimeLoginDetectionAuthenticationSuccessHandler extends
SimpleUrlAuthenticationSuccessHandler {
private OAuthProviderSupport providerSupport = new CoreOAuthProviderSupport();
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
private String firstTimeLoginUrl;
private final OAuthProviderTokenServices tokenServices;
public FirstTimeLoginDetectionAuthenticationSuccessHandler(final OAuthProviderTokenServices oauthProviderTokenServices) {
this.tokenServices = oauthProviderTokenServices;
}
@Override
public void onAuthenticationSuccess(final HttpServletRequest request,
final HttpServletResponse response,
final Authentication authentication) throws ServletException,
IOException {
// hardcoded success url
String authSuccessUrl = "/oauth/confirm_access"; // request.getParameter("successUrl");
Map<String, String> oauthParams = this.providerSupport.parseParameters(request);
String oauthToken = retrieveOAuthToken(oauthParams);
if (StringUtils.isBlank(oauthToken)) {
// throw exception
}
OAuthProviderTokenImpl token = (OAuthProviderTokenImpl) this.tokenServices.getToken(oauthToken);
PlatformUser loggedInUser = (PlatformUser) authentication.getPrincipal();
token.setUserAuthentication(new UsernamePasswordAuthenticationToken(loggedInUser, loggedInUser, loggedInUser.getAuthorities()));
String targetUrl = this.determineTargetUrl(request, response);
if (loggedInUser.isFirstTimeLoginRemaining()) {
// request.getSession().setAttribute("firsttimeloginview", targetUrl);
request.setAttribute("firsttimeloginview", targetUrl);
targetUrl = this.firstTimeLoginUrl;
}
clearAuthenticationAttributes(request);
getRedirectStrategy().sendRedirect(request, response, authSuccessUrl + "?oauth_token=" + oauthToken);
}
private String retrieveOAuthToken(Map<String, String> oauthParams) {
return oauthParams.get(OAuthConsumerParameter.oauth_token.toString());
}
@Override
protected void handle(final HttpServletRequest request, final HttpServletResponse response, final Authentication authentication) throws IOException {
String targetUrl = this.determineTargetUrl(request, response);
PlatformUser loggedInUser = (PlatformUser) authentication.getPrincipal();
if (loggedInUser.isFirstTimeLoginRemaining()) {
targetUrl = this.firstTimeLoginUrl;
}
if (response.isCommitted()) {
this.logger.debug("Response has already been committed. Unable to redirect to " + targetUrl);
return;
}
this.redirectStrategy.sendRedirect(request, response, targetUrl);
}
public String getFirstTimeLoginUrl() {
return this.firstTimeLoginUrl;
}
public void setFirstTimeLoginUrl(final String firstTimeLoginUrl) {
this.firstTimeLoginUrl = firstTimeLoginUrl;
}
}
@@ -1,77 +0,0 @@
package org.mifosng.platform.infrastructure;
import org.apache.commons.lang.StringUtils;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.binding.validation.ValidationContext;
public class FirstTimeLoginFormBean {
private String oldUsername;
private String username;
private String password;
private String successView;
public void validateUpdateUsernamePasswordDetails(final ValidationContext validationContext) {
MessageContext messageContext = validationContext.getMessageContext();
if (StringUtils.isBlank(this.username)) {
MessageBuilder builder = new MessageBuilder().error().source("username")
.codes(new String[] { "username.blank" })
.defaultText("Username cannot be empty.")
.args(new Object[] {});
messageContext.addMessage(builder.build());
}
if (this.oldUsername.trim().equalsIgnoreCase(this.username.trim())) {
MessageBuilder builder = new MessageBuilder().error().source("username")
.codes(new String[] { "username.same.as.old.username" })
.defaultText("The new username cannot be the same as the old username.")
.args(new Object[] {});
messageContext.addMessage(builder.build());
}
if (StringUtils.isBlank(this.password)) {
MessageBuilder builder = new MessageBuilder().error().source("password")
.codes(new String[] { "password.blank" })
.defaultText("Password cannot be empty.")
.args(new Object[] {});
messageContext.addMessage(builder.build());
}
}
public String getOldUsername() {
return this.oldUsername;
}
public void setOldUsername(final String oldUsername) {
this.oldUsername = oldUsername;
}
public String getUsername() {
return this.username;
}
public void setUsername(final String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(final String password) {
this.password = password;
}
public String getSuccessView() {
return this.successView;
}
public void setSuccessView(final String successView) {
this.successView = successView;
}
}
@@ -5,13 +5,11 @@ import org.mifosng.data.command.SignupCommand;
import org.mifosng.platform.WritePlatformService;
import org.mifosng.platform.exceptions.InvalidSignupException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
@@ -20,8 +18,8 @@ import org.springframework.web.servlet.ModelAndView;
* @deprecated - remove signup functionality for now.
*/
@Deprecated
@Controller
@SessionAttributes("signupFormBean")
//@Controller
//@SessionAttributes("signupFormBean")
public class SignupController {
private final WritePlatformService signupPlatformService;
@@ -1,127 +0,0 @@
package org.mifosng.platform.oauthconsumer.domain;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.springframework.data.jpa.domain.AbstractPersistable;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth.common.signature.SharedConsumerSecret;
import org.springframework.security.oauth.common.signature.SignatureSecret;
import org.springframework.security.oauth.provider.ResourceSpecificConsumerDetails;
/**
* TODO - revisit when tackling better administration support for oauth consumer control with OAuth 2 implementation.
*/
@Entity
@Table(name = "admin_oauth_consumer_application")
public class OauthConsumerDetail extends AbstractPersistable<Long> implements
ResourceSpecificConsumerDetails {
@Column(name = "app_key", nullable = false, unique = true, length=50)
private String consumerKey;
@Column(name = "app_shared_secret", nullable = false, unique = true, length=50)
private String consumerSharedSecret;
@Column(name = "app_name", nullable = false, unique = true, length=100)
private String consumerName;
@SuppressWarnings("unused")
@Column(name = "app_description", nullable = true, length=500)
private String consumerDescription;
@SuppressWarnings("unused")
@Column(name = "app_developedby", nullable = true, length=100)
private String consumerDevelopedBy;
@SuppressWarnings("unused")
@Column(name = "app_location_url", nullable = true, length=200)
private String consumerLocationUrl;
@Column(name = "resource_name", nullable = false)
private String resourceName;
@Column(name = "resource_description", nullable = false)
private String resourceDescription;
@Transient
private List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
@Transient
private boolean requiredToObtainAuthenticatedToken = true;
// for jpa/hibernate
protected OauthConsumerDetail() {
//
}
public OauthConsumerDetail(String consumerKey, String consumerName, String consumerDescription, String consumerDevelopedby, String consumerLocationUrl,
String resourceName, String resourceDesription) {
this.consumerKey = consumerKey;
this.consumerName = consumerName;
this.consumerDescription = consumerDescription;
this.consumerDevelopedBy = consumerDevelopedby;
this.consumerLocationUrl = consumerLocationUrl;
this.resourceName = resourceName;
resourceDescription = resourceDesription;
}
@Override
public String getConsumerKey() {
return this.consumerKey;
}
@Override
public String getConsumerName() {
return this.consumerName;
}
@Override
public SignatureSecret getSignatureSecret() {
return new SharedConsumerSecret(this.consumerSharedSecret);
}
@Override
public List<GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getResourceName() {
return this.resourceName;
}
@Override
public String getResourceDescription() {
return this.resourceDescription;
}
/**
* Whether this consumer is required to obtain an authenticated oauth token.
*
* @return Whether this consumer is required to obtain an authenticated
* oauth token.
*/
public boolean isRequiredToObtainAuthenticatedToken() {
return requiredToObtainAuthenticatedToken;
}
/**
* Whether this consumer is required to obtain an authenticated oauth token.
*
* @param requiredToObtainAuthenticatedToken
* Whether this consumer is required to obtain an authenticated
* oauth token.
*/
public void setRequiredToObtainAuthenticatedToken(
boolean requiredToObtainAuthenticatedToken) {
this.requiredToObtainAuthenticatedToken = requiredToObtainAuthenticatedToken;
}
}
@@ -1,11 +0,0 @@
package org.mifosng.platform.oauthconsumer.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface OauthConsumerDetailRepository extends
JpaRepository<OauthConsumerDetail, Long>,
JpaSpecificationExecutor<OauthConsumerDetail> {
OauthConsumerDetail findByConsumerKey(String consumerKey);
}
@@ -1,85 +0,0 @@
package org.mifosng.platform.rest;
import java.util.ArrayList;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.mifosng.data.AuthenticatedUserData;
import org.mifosng.oauth.CustomOAuthProviderTokenServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth.provider.token.OAuthProviderTokenImpl;
import org.springframework.stereotype.Component;
@Path("/protected/user")
@Component
@Scope("singleton")
public class UserResource {
@Autowired
private CustomOAuthProviderTokenServices oauthProviderTokenServices;
@GET
@Path("{accessToken}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response retrieveClientAccount(
@PathParam("accessToken") final String oauthToken) {
OAuthProviderTokenImpl token = (OAuthProviderTokenImpl) this.oauthProviderTokenServices.getTokenByNonEncodedKey(oauthToken);
if (token == null) {
token = (OAuthProviderTokenImpl) this.oauthProviderTokenServices.getToken(oauthToken);
}
Authentication auth = null;
if (token != null && token.isAccessToken()) {
auth = token.getUserAuthentication();
}
Collection<String> permissions = new ArrayList<String>();
if (auth != null) {
for (GrantedAuthority authority : auth.getAuthorities()) {
permissions.add(authority.getAuthority());
}
}
AuthenticatedUserData authenticatedUserData = new AuthenticatedUserData(permissions);
if (auth != null) {
authenticatedUserData.setUsername(((UserDetails)auth.getPrincipal()).getUsername());
}
return Response.ok().entity(authenticatedUserData).build();
}
@GET
@Path("{accessToken}/signout")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response userSignOut(@PathParam("accessToken") final String oauthToken, @Context HttpServletRequest request) {
this.oauthProviderTokenServices.removeTokenByNonEncodedKey(oauthToken);
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(null);
return Response.ok().build();
}
}
@@ -1,85 +0,0 @@
package org.mifosng.platform.security;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mifosng.oauth.CustomOAuthProviderTokenServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth.common.OAuthConsumerParameter;
import org.springframework.security.oauth.provider.ConsumerDetails;
import org.springframework.security.oauth.provider.ConsumerDetailsService;
import org.springframework.security.oauth.provider.OAuthProviderSupport;
import org.springframework.security.oauth.provider.filter.CoreOAuthProviderSupport;
import org.springframework.security.oauth.provider.token.OAuthProviderToken;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class AccessConfirmationController {
@Autowired
private CustomOAuthProviderTokenServices tokenServices;
@Autowired
private ConsumerDetailsService consumerDetailsService;
private OAuthProviderSupport providerSupport = new CoreOAuthProviderSupport();
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@RequestMapping("/oauth/confirm_access")
public ModelAndView getAccessConfirmation(final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
Map<String, String> oauthParams = this.providerSupport.parseParameters(request);
String oauthToken = retrieveOAuthToken(oauthParams);
if (oauthToken == null) {
throw new IllegalArgumentException(
"A request token to authorize must be provided.");
}
OAuthProviderToken providerToken = this.tokenServices.getToken(oauthToken);
ConsumerDetails consumer = this.consumerDetailsService
.loadConsumerByConsumerKey(providerToken.getConsumerKey());
String callback = retrieveCallbackurl(oauthParams);
TreeMap<String, Object> model = new TreeMap<String, Object>();
model.put(OAuthConsumerParameter.oauth_token.toString(), oauthToken);
if (callback != null) {
model.put(OAuthConsumerParameter.oauth_callback.toString(), callback);
}
model.put("consumer", consumer);
// check if user is fully authenticated here and if not redirect to login page passing oauth token info etc
SecurityContext context = SecurityContextHolder.getContext();
if (context.getAuthentication() instanceof AnonymousAuthenticationToken) {
model.put("successUrl", "/oauth/confirm_access");
return new ModelAndView("login", model);
}
if ("mifosng-ui-consumer-key".equalsIgnoreCase(consumer.getConsumerKey())) {
response.sendRedirect("authorize?requestToken=" + oauthToken);
return null;
} else {
redirectStrategy.sendRedirect(request, response, "access_confirmation");
return new ModelAndView("access_confirmation", model);
}
}
private String retrieveOAuthToken(Map<String, String> oauthParams) {
return oauthParams.get(OAuthConsumerParameter.oauth_token.toString());
}
private String retrieveCallbackurl(Map<String, String> oauthParams) {
return oauthParams.get(OAuthConsumerParameter.oauth_callback.toString());
}
}
@@ -17,7 +17,8 @@
<tx:annotation-driven />
<context:component-scan base-package="org.mifosng.platform.rest, org.mifosng.platform.security, org.mifosng.platform.infrastructure, org.mifosng.platform.*.domain, org.mifosng.platform, org.mifosng.demo">
<context:component-scan base-package="org.mifosng.platform.rest, org.mifosng.platform.security, org.mifosng.platform.infrastructure,
org.mifosng.platform.*.domain, org.mifosng.platform, org.mifosng.demo">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</context:component-scan>
@@ -27,28 +28,6 @@
<jpa:repositories base-package="org.mifosng.platform.*.domain" />
<import resource="infrastructure.xml" />
<!--
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongo" />
<constructor-arg value="test" />
</bean>
<bean class="org.springframework.data.mongodb.core.MongoExceptionTranslator" />
<mongo:mongo id="mongo" host="localhost" port="27017" />
<mongo:repositories base-package="org.mifosng.platform.*.mongo" />
<bean class="org.springframework.data.persistence.document.mongodb.MongoDocumentBacking" factory-method="aspectOf">
<property name="changeSetPersister" ref="mongoChangeSetPersister"/>
</bean>
<bean id="mongoChangeSetPersister" class="org.springframework.data.persistence.document.mongodb.MongoChangeSetPersister">
<property name="mongoTemplate" ref="mongoTemplate"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
-->
<import resource="securityContext.xml" />
</beans>
@@ -1,138 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/security/oauth
http://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd">
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<sec:filter-chain pattern="/resources/**" filters="none" />
<sec:filter-chain pattern="/api/open/**" filters="none" />
<sec:filter-chain pattern="/api/v1/**" filters="none" />
<sec:filter-chain pattern="/**" filters="populateSecurityContextFilter, customAuthenticationFilter,
oauthRequestTokenFilter, oauthUserAuthorizationFilter, oauthAccessTokenFilter, oauthProtectedResourceFilter,
filterSecurityInterceptor" />
</list>
</constructor-arg>
</bean>
<bean id="oauthProviderTokenServicesDelegate" class="org.mifosng.oauth.RemovableInMemoryProviderTokenServices" />
<bean id="tokenServices" class="org.mifosng.oauth.CustomTokenServices">
<constructor-arg ref="oauthProviderTokenServicesDelegate" />
</bean>
<bean id="roleBasedAuthenticationSuccessHandler" class="org.mifosng.platform.infrastructure.FirstTimeLoginDetectionAuthenticationSuccessHandler">
<constructor-arg ref="tokenServices" />
<property name="defaultTargetUrl" value="/home" />
<property name="alwaysUseDefaultTargetUrl" value="true" />
<property name="firstTimeLoginUrl" value="/firsttimelogin" />
</bean>
<bean id="customAuthenticationFalureHandler" class="org.mifosng.platform.infrastructure.CustomAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login" />
</bean>
<http create-session="stateless" use-expressions="true" pattern="/api/**">
<intercept-url pattern="/api/**" access="isFullyAuthenticated()" />
<http-basic />
</http>
<bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy" />
<bean id="customAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler" ref="roleBasedAuthenticationSuccessHandler" />
<property name="authenticationFailureHandler" ref="customAuthenticationFalureHandler" />
<property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy" />
</bean>
<bean id="populateSecurityContextFilter" class="org.mifosng.oauth.OAuthParametersAwareSecurityContextPerRequestFilter">
<constructor-arg ref="tokenServices" />
</bean>
<bean id="oauthConsumerDetailsService" class="org.mifosng.oauth.MifosNgConsumerDetailsService" />
<bean id="oauthRequestTokenFilter" class="org.springframework.security.oauth.provider.filter.UnauthenticatedRequestTokenProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/request_token" />
<property name="tokenServices" ref="tokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="customAuthenticationProvider" />
</sec:authentication-manager>
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<constructor-arg value="256"/>
</bean>
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="256"/>
</beans:bean>
<bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<property name="userPropertyToUse" value="id"/>
</bean>
<bean id="userDetailsService" class="org.mifosng.platform.security.PlatformUserDetailsServiceImpl" />
<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<beans:property name="userPropertyToUse" value="id"/>
</beans:bean>
<beans:bean id="userDetailsService" class="org.mifosng.platform.security.PlatformUserDetailsServiceImpl" />
<bean id="customAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder" ref="passwordEncoder" />
<property name="saltSource" ref="saltSource" />
</bean>
<bean id="oauthRandomValueVerifierServices" class="org.springframework.security.oauth.provider.verifier.RandomValueVerifierServices" />
<bean id="oauthAuthorizationSuccessHandler" class="org.springframework.security.oauth.provider.filter.UserAuthorizationSuccessfulAuthenticationHandler" />
<bean id="oauthUserAuthorizationFilter" class="org.springframework.security.oauth.provider.filter.UserAuthorizationProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/authorize" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="tokenServices" ref="tokenServices" />
<property name="verifierServices" ref="oauthRandomValueVerifierServices" />
<property name="authenticationSuccessHandler" ref="oauthAuthorizationSuccessHandler" />
</bean>
<bean id="oauthAccessTokenFilter" class="org.springframework.security.oauth.provider.filter.AccessTokenProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/access_token" />
<property name="tokenServices" ref="tokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="oauthProtectedResourceFilter" class="org.mifosng.oauth.CustomProtectedResourceProcessingFilter">
<property name="tokenServices" ref="tokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
<bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
</list>
</property>
</bean>
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="securityMetadataSource">
<sec:filter-security-metadata-source use-expressions="true">
<sec:intercept-url pattern="/login" access="isAnonymous()" />
<sec:intercept-url pattern="/logout" access="isAnonymous()" />
<sec:intercept-url pattern="/signup" access="isAnonymous()" />
<sec:intercept-url pattern="/pentahoreport*" access="isAnonymous()" />
<sec:intercept-url pattern="/exportcsv*" access="isAnonymous()" />
<sec:intercept-url pattern="/oauth/authorize" access="isAnonymous()" />
<sec:intercept-url pattern="/oauth/access_token" access="isAnonymous()" />
<sec:intercept-url pattern="/oauth/confirm_access*" access="isAnonymous() or isFullyAuthenticated()" />
<sec:intercept-url pattern="/api/protected/**" access="isFullyAuthenticated()" />
<sec:intercept-url pattern="/**" access="isFullyAuthenticated()" />
</sec:filter-security-metadata-source>
</property>
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
</bean>
</beans>
<beans:bean id="customAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
<beans:property name="saltSource" ref="saltSource" />
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
</beans:beans>
@@ -1,241 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:oauth="http://www.springframework.org/schema/security/oauth"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security/oauth
http://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd">
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="256"/>
</beans:bean>
<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<beans:property name="userPropertyToUse" value="id"/>
</beans:bean>
<beans:bean id="userDetailsService" class="org.mifosng.platform.security.PlatformUserDetailsServiceImpl" />
<beans:bean id="customAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
<beans:property name="saltSource" ref="saltSource" />
</beans:bean>
<beans:bean id="roleBasedAuthenticationSuccessHandler" class="org.mifosng.platform.infrastructure.FirstTimeLoginDetectionAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/home" />
<beans:property name="alwaysUseDefaultTargetUrl" value="true" />
<beans:property name="firstTimeLoginUrl" value="/firsttimelogin" />
</beans:bean>
<beans:bean id="customAuthenticationFalureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login" />
</beans:bean>
<beans:bean id="sessionAuthenticationStrategy" class="org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy" />
<beans:bean id="customAuthenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler" ref="roleBasedAuthenticationSuccessHandler" />
<beans:property name="authenticationFailureHandler" ref="customAuthenticationFalureHandler" />
<beans:property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy" />
</beans:bean>
<beans:bean id="mySecurityContextRepository" class="org.mifosng.oauth.InMemoryOAuthTokenAwareSecurityContextRepository">
<beans:constructor-arg ref="tokenServices"/>
</beans:bean>
<!--
<beans:bean id="mySecurityContextPersistenceFilter" class="org.mifosng.oauth.OAuthTokenAwareSecurityContextPersistenceFilter">
<beans:constructor-arg ref="mySecurityContextRepository"/>
</beans:bean>
-->
<global-method-security pre-post-annotations="enabled" />
<http pattern="/" security="none" />
<http pattern="/resources/**" security="none" />
<http pattern="/api/open/**" security="none" />
<beans:bean id="loginForm" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login" />
</beans:bean>
<!-- SecurityContext no longer stored in session -->
<!--
on successful authentication, need to store token with association against authentication object
-->
<beans:bean id="requestCacheFilter" class="org.springframework.security.web.savedrequest.RequestCacheAwareFilter" />
<!-- security-context-repository-ref="mySecurityContextRepository" -->
<http auto-config="false" create-session="always" use-expressions="true" pattern="/**"
entry-point-ref="loginForm" access-denied-page="/login"
>
<intercept-url pattern="/login" access="isAnonymous()" />
<intercept-url pattern="/logout" access="isAnonymous()" />
<intercept-url pattern="/pentahoreport*" access="isAnonymous()" />
<intercept-url pattern="/oauth/request_token" access="isAnonymous()" />
<intercept-url pattern="/oauth/confirm_access" access="isFullyAuthenticated()" />
<intercept-url pattern="/oauth/authorize" access="isFullyAuthenticated()" />
<intercept-url pattern="/oauth/access_token" access="isFullyAuthenticated()" />
<intercept-url pattern="/api/protected/**" access="isFullyAuthenticated()" />
<intercept-url pattern="/**" access="isFullyAuthenticated()" />
<!--
<custom-filter ref="customAuthenticationFilter" position="FORM_LOGIN_FILTER" />
<custom-filter ref="requestCacheFilter" after="FORM_LOGIN_FILTER"/>
-->
<logout logout-success-url="/logout" />
</http>
<beans:bean id="oauthProviderTokenServicesDelegate" class="org.mifosng.oauth.RemovableInMemoryProviderTokenServices" />
<beans:bean id="tokenServices" class="org.mifosng.oauth.CustomTokenServices">
<beans:constructor-arg ref="oauthProviderTokenServicesDelegate" />
</beans:bean>
<beans:bean id="consumerDetails" class="org.mifosng.oauth.MifosNgConsumerDetailsService" />
<oauth:provider
consumer-details-service-ref="consumerDetails"
token-services-ref="tokenServices"
request-token-url="/oauth/request_token"
authenticate-token-url="/oauth/authorize"
access-token-url="/oauth/access_token"
authentication-failed-url="/oauth/confirm_access"
access-granted-url="/request_token_authorized"
require10a="false"/>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
</beans:beans>
<!--
<security:global-method-security pre-post-annotations="enabled" />
<security:http pattern="/resources/**" security="none"/>
<security:http pattern="/api/open/**" security="none"/>
<security:http auto-config='true' access-denied-page="/login">
<security:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/logout" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/oauth/**" access="ROLE_USER" />
<security:intercept-url pattern="/api/protected/**" access="ROLE_USER" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login authentication-failure-url="/login" default-target-url="/index" login-page="/login" />
<security:logout logout-success-url="/logout" />
</security:http>
-->
<!--
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name="securityContextRepository" ref="securityContextRepository" />
</bean>
<bean id="securityContextRepository" class="org.springframework.security.web.context.NullSecurityContextRepository" />
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="/logout" />
<constructor-arg>
<list><bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" /></list>
</constructor-arg>
</bean>
<bean id="servletApiFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter" />
<bean id="anonymousAuthenticationFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter" >
<property name="key" value="SomeUniqueKeyForThisApplication" />
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
</bean>
<bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter" >
<constructor-arg ref="securityContextRepository" />
</bean>
<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="loginForm" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="securityMetadataSource">
<security:filter-security-metadata-source>
<security:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/logout" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/signup" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/pentahoreport*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/oauth/**" access="IS_AUTHENTICATED_FULLY" />
<security:intercept-url pattern="/api/protected/**" access="IS_AUTHENTICATED_FULLY" />
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
</security:filter-security-metadata-source>
</property>
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
</bean>
-->
<!-- org.springframework.security.oauth.provider.token.InMemorySelfCleaningProviderTokenServices -->
<!--
<bean id="oauthProviderTokenServicesDelegate" class="org.springframework.security.oauth.provider.token.InMemorySelfCleaningProviderTokenServices">
<property name="cleanupIntervalSeconds" value="30" />
</bean>
-->
<!--
<bean id="oauthRequestTokenFilter" class="org.springframework.security.oauth.provider.filter.UnauthenticatedRequestTokenProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/request_token" />
<property name="tokenServices" ref="oauthProviderTokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="oauthRandomValueVerifierServices" class="org.springframework.security.oauth.provider.verifier.RandomValueVerifierServices" />
<bean id="oauthAuthorizationSuccessHandler" class="org.springframework.security.oauth.provider.filter.UserAuthorizationSuccessfulAuthenticationHandler" />
<bean id="oauthUserAuthorizationFilter" class="org.springframework.security.oauth.provider.filter.UserAuthorizationProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/authorize" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="tokenServices" ref="oauthProviderTokenServices" />
<property name="verifierServices" ref="oauthRandomValueVerifierServices" />
<property name="authenticationSuccessHandler" ref="oauthAuthorizationSuccessHandler" />
</bean>
<bean id="oauthAccessTokenFilter" class="org.springframework.security.oauth.provider.filter.AccessTokenProcessingFilter">
<property name="filterProcessesUrl" value="/oauth/access_token" />
<property name="tokenServices" ref="oauthProviderTokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="oauthProtectedResourceFilter" class="org.mifosng.oauth.CustomProtectedResourceProcessingFilter">
<property name="tokenServices" ref="oauthProviderTokenServices" />
<property name="consumerDetailsService" ref="oauthConsumerDetailsService" />
</bean>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<filter-chain pattern="/resources/**" filters="none" />
<filter-chain pattern="/api/open/**" filters="none" />
<filter-chain pattern="/**" filters="securityContextPersistenceFilter, logoutFilter, customAuthenticationFilter,
requestCacheFilter, servletApiFilter, anonymousAuthenticationFilter, sessionManagementFilter, exceptionTranslationFilter,
oauthRequestTokenFilter, oauthUserAuthorizationFilter, oauthAccessTokenFilter, oauthProtectedResourceFilter,
filterSecurityInterceptor" />
</list>
</constructor-arg>
</bean>
-->
@@ -18,7 +18,6 @@
<param-value>classpath*:META-INF/spring/appContext.xml</param-value>
</context-param>
<!--
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
@@ -28,18 +27,19 @@
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
<filter>
<filter-name>filterChainProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>filterChainProxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<filter>
<filter-name>filterChainProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>filterChainProxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>