diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java index 1126d37ce..7f0d08a58 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java @@ -67,8 +67,17 @@ public class OAuthConfirmationController { @PreAuthorize("hasRole('ROLE_USER')") @RequestMapping("/oauth/confirm_access") - public ModelAndView confimAccess(Map<String, Object> model, @ModelAttribute("authorizationRequest") AuthorizationRequest clientAuth) { + public String confimAccess(Map<String, Object> model, @ModelAttribute("authorizationRequest") AuthorizationRequest clientAuth) { + // Check the "prompt" parameter to see if we need to do special processing + String prompt = clientAuth.getAuthorizationParameters().get("prompt"); + if ("none".equals(prompt)) { + // we're not supposed to prompt, so "return an error" + logger.info("Client requested no prompt, returning 403 from confirmation endpoint"); + model.put("code", HttpStatus.FORBIDDEN); + return "httpCodeView"; + } + //AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest"); ClientDetails client = null; @@ -79,18 +88,19 @@ public class OAuthConfirmationController { logger.error("confirmAccess: OAuth2Exception was thrown when attempting to load client: " + e.getStackTrace().toString()); model.put("code", HttpStatus.BAD_REQUEST); - return new ModelAndView("httpCodeView"); + return "httpCodeView"; } catch (IllegalArgumentException e) { logger.error("confirmAccess: IllegalArgumentException was thrown when attempting to load client: " + e.getStackTrace().toString()); model.put("code", HttpStatus.BAD_REQUEST); - return new ModelAndView("httpCodeView"); + return "httpCodeView"; } if (client == null) { logger.error("confirmAccess: could not find client " + clientAuth.getClientId()); model.put("code", HttpStatus.NOT_FOUND); - return new ModelAndView("httpCodeView"); } + return "httpCodeView"; + } model.put("auth_request", clientAuth); model.put("client", client); @@ -98,14 +108,6 @@ public class OAuthConfirmationController { String redirect_uri = clientAuth.getAuthorizationParameters().get("redirect_uri"); model.put("redirect_uri", redirect_uri); - - - /* - Map<String, Boolean> scopes = new HashMap<String, Boolean>(); - for (String scope : clientAuth.getScope()) { - scopes.put(scope, Boolean.TRUE); - } - */ Set<SystemScope> scopes = scopeService.fromStrings(clientAuth.getScope()); @@ -123,7 +125,7 @@ public class OAuthConfirmationController { model.put("scopes", sortedScopes); - return new ModelAndView("approve", model); + return "approve"; } /** diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/PromptFilter.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/PromptFilter.java new file mode 100644 index 000000000..b3bcfa798 --- /dev/null +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/PromptFilter.java @@ -0,0 +1,76 @@ +/** + * + */ +package org.mitre.openid.connect.filter; + +import java.io.IOException; + +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 javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.savedrequest.HttpSessionRequestCache; +import org.springframework.security.web.savedrequest.SavedRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.GenericFilterBean; + +import com.google.common.base.Strings; + +/** + * @author jricher + * + */ +@Component("promptFilter") +public class PromptFilter extends GenericFilterBean { + + private Logger logger = LoggerFactory.getLogger(PromptFilter.class); + + /** + * + */ + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + if (!Strings.isNullOrEmpty(request.getParameter("prompt"))) { + // we have a "prompt" parameter + + if (request.getParameter("prompt").equals("none")) { + logger.info("Client requested no prompt"); + // see if the user's logged in + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + + if (auth != null) { + // user's been logged in already (by session management) + // we're OK, continue without prompting + chain.doFilter(req, res); + } else { + // user hasn't been logged in, we need to "return an error" + logger.info("User not logged in, no prompt requested, returning 403 from filter"); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"); + return; + } + + } else { + // prompt parameter is a value we don't care about, not our business + chain.doFilter(req, res); + } + + } else { + // no prompt parameter, not our business + chain.doFilter(req, res); + } + + } + +} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java index e041bafdb..78a3e18fe 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java @@ -125,7 +125,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { String clientId = authorizationRequest.getClientId(); ClientDetails client = clientDetailsService.loadClientByClientId(clientId); - // find out if we're supposed to prompt the user or not + // find out if we're supposed to force a prompt on the user or not String prompt = authorizationRequest.getAuthorizationParameters().get("prompt"); if (!"consent".equals(prompt)) { // if the prompt parameter is set to "consent" then we can't use approved sites or whitelisted sites diff --git a/openid-connect-server/src/main/webapp/WEB-INF/user-context.xml b/openid-connect-server/src/main/webapp/WEB-INF/user-context.xml index b30f5b38c..f731a1fbf 100644 --- a/openid-connect-server/src/main/webapp/WEB-INF/user-context.xml +++ b/openid-connect-server/src/main/webapp/WEB-INF/user-context.xml @@ -25,10 +25,11 @@ <security:http pattern="/login**" use-expressions="true" entry-point-ref="http403EntryPoint"> <security:intercept-url pattern="/login**" access="permitAll"/> </security:http> - + <security:http disable-url-rewriting="true" use-expressions="true"> <security:form-login login-page="/login" authentication-failure-url="/login?error=failure" authentication-success-handler-ref="authenticationTimeStamper" /> <security:intercept-url pattern="/**" access="permitAll" /> + <security:custom-filter ref="promptFilter" after="SECURITY_CONTEXT_FILTER" /> <security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> <security:logout logout-url="/logout" /> <security:anonymous />