001/******************************************************************************* 002 * Copyright 2018 The MIT Internet Trust Consortium 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 *******************************************************************************/ 016/** 017 * 018 */ 019package org.mitre.oauth2.service.impl; 020 021import org.mitre.openid.connect.config.ConfigurationPropertiesBean; 022import org.mitre.openid.connect.service.BlacklistedSiteService; 023import org.springframework.beans.factory.annotation.Autowired; 024import org.springframework.security.oauth2.common.exceptions.InvalidRequestException; 025import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; 026import org.springframework.security.oauth2.provider.ClientDetails; 027import org.springframework.security.oauth2.provider.endpoint.DefaultRedirectResolver; 028import org.springframework.stereotype.Component; 029 030import com.google.common.base.Strings; 031 032/** 033 * 034 * A redirect resolver that knows how to check against the blacklisted URIs 035 * for forbidden values. Can be configured to do strict string matching also. 036 * 037 * @author jricher 038 * 039 */ 040@Component("blacklistAwareRedirectResolver") 041public class BlacklistAwareRedirectResolver extends DefaultRedirectResolver { 042 043 @Autowired 044 private BlacklistedSiteService blacklistService; 045 046 @Autowired 047 private ConfigurationPropertiesBean config; 048 049 private boolean strictMatch = true; 050 051 /* (non-Javadoc) 052 * @see org.springframework.security.oauth2.provider.endpoint.RedirectResolver#resolveRedirect(java.lang.String, org.springframework.security.oauth2.provider.ClientDetails) 053 */ 054 @Override 055 public String resolveRedirect(String requestedRedirect, ClientDetails client) throws OAuth2Exception { 056 String redirect = super.resolveRedirect(requestedRedirect, client); 057 if (blacklistService.isBlacklisted(redirect)) { 058 // don't let it go through 059 throw new InvalidRequestException("The supplied redirect_uri is not allowed on this server."); 060 } else { 061 // not blacklisted, passed the parent test, we're fine 062 return redirect; 063 } 064 } 065 066 /* (non-Javadoc) 067 * @see org.springframework.security.oauth2.provider.endpoint.DefaultRedirectResolver#redirectMatches(java.lang.String, java.lang.String) 068 */ 069 @Override 070 protected boolean redirectMatches(String requestedRedirect, String redirectUri) { 071 072 if (isStrictMatch()) { 073 // we're doing a strict string match for all clients 074 return Strings.nullToEmpty(requestedRedirect).equals(redirectUri); 075 } else { 076 // otherwise do the prefix-match from the library 077 return super.redirectMatches(requestedRedirect, redirectUri); 078 } 079 080 } 081 082 /** 083 * @return the strictMatch 084 */ 085 public boolean isStrictMatch() { 086 if (config.isHeartMode()) { 087 // HEART mode enforces strict matching 088 return true; 089 } else { 090 return strictMatch; 091 } 092 } 093 094 /** 095 * Set this to true to require exact string matches for all redirect URIs. (Default is false) 096 * 097 * @param strictMatch the strictMatch to set 098 */ 099 public void setStrictMatch(boolean strictMatch) { 100 this.strictMatch = strictMatch; 101 } 102 103 104 105}