I am using following spring security saml repo from github:
https://github.com/spring-projects/spring-security-saml/tree/master/sample
Whenever I try to update the SSO url, for e.g. localhost:8100/saml/ddo, instead of /saml/sso, browser gets stuck in infinite loops.
(I have followed the steps mentioned in readme and updated the url on okta as well in application to test)
Sample code and config enclosed in:
Spring secuirty saml issue
EDIT:
I did what below answer suggested,but I am getting the Incoming SAML message is invalid..
On debugging, I found that attemptAuthentication in SAMLProcessingFilter, the location in endpoint that are added still contain the /api/saml/SSO instead of /api/saml/ddo
and that's why getEndpoint method in SamlUtil throws excpetion with following line:
throw new SAMLException("Endpoint with message binding " + messageBinding + " and URL " + requestURL + " wasn't found in local metadata");
because the requestUrl and endpoint location do not match.
I also checked my metadata.xml but it does not contain any info related to these urls.
In the MetaDataGenerator class method getSAMLWebSSOProcessingFilterPath, the samlWebSSOFilter is null and that's why the default filter url: /saml/SSO is returned. I am trying to figure out how to set this value at runtime?
I understand that there is a method with name: setSamlWebSSOFilter, and everything works correct if I provide the url /saml/ddo at the time of startup. But I am not able to make this work if config is changed at runtime.
Any idea how can I move forward?
Setting field filterProcessesUrl on bean samlWebSSOProcessingFilter to value /saml/ddo should solve the problem.
Related
I'm building a Single Page Application using Spring Social and Spring Security generated by JHipster.
I'm trying to capture the original query parameters after a user has been authenticated by some social authentication provider.
Example:
calling /signin/someprovider?show=someEntityId and after a successful authentication redirects the user to /signup/ , I need a way to fetch 'someEntityID'.
I assume different http calls make it difficult to pass/store the parameters around.
Is there some Spring built-in functionality I can use/reuse or how does one solve this problem?
UPDATE
The thread of requests looks like this:
(1) browser-> http://localhost:9060/signin/authenticationProvider?show=**someEntityId**
<- redirect to https://authenticationProvider... &state=SomeState
(2) browser -> https://authenticationProvider
<- redirect to http://localhost:9060/signin/google?state=SomeState&code=SomeCode
(3) browser-> http://localhost:9060/signin/authenticationProvider?state=SomeState&code=SomeCode
<- redirect to http://localhost:9060/social/signup
(4) browser -> http://localhost:9060/social/signup
This ends up in
#GetMapping("/signup")
public RedirectView signUp(WebRequest webRequest, #CookieValue(name = "NG_TRANSLATE_LANG_KEY", required = false, defaultValue = Constants.DEFAULT_LANGUAGE) String langKey) {
try {
Connection<?> connection = providerSignInUtils.getConnectionFromSession(webRequest);
socialService.createSocialUser(connection, langKey.replace("\"", ""));
At this point it want to call a function with the original parameter someEntityId.
According to google oauth2 redirect_uri with several parameters the ?show=someEntityId parameter should be encoded in the state parameter of the Oauth2 request in order to survive
from (1) to (3). In (3) the state parameter has to be added to the redirect uri, such that the original parameter can be decoded in (4).
It looks like a lot of work, or am I missing something? It would be nice if there would be a way to have a session variable in which I could store the parameters at (1) and fetch them again when in (4).
Since version 1.1.3 Spring Social creates the state parameter on its own and uses it as a CSRF token, see https://pivotal.io/security/cve-2015-5258 - therefore you can (and should not) encode additional parameters in the state parameter.
Instead if the provider sign is enabled with a ProviderSignInController, a ProviderSignInInterceptor can be used to store such parameters intermediately in the session (in preSignIn(...) and postSignIn(...)).
I guess there is a similar approach if a SocialAuthenticationFilter is used.
I have been trying to configure the oauth2 provider plugin in my grails application, but I am facing certain issues, and other than the plugin documentation, I didn't find any other sources that could help.
I have followed all the stepd mentioned in the doc, and made changes in Config.groovy
Now hitting localhost:8080/oauth/authorize?response_type=code&client_id=my-client&scope=read should redirect me to login page which it does.
After login however, I want authorization window to appear where user accepts or rejects granting authorization. I am however just getting a JSON result:
{"url":"http://localhost:8080/oauth/authorize?response_type=code&client_id=my-client&scope=read","success":true}
Why am I not getting an authorization prompt instead? What am I missing here?
Okay. So I have made some changes:
grails.plugin.springsecurity.filterChain.filterNames = [
'cookieSessionFilter',
'securityContextPersistenceFilter', 'statelessSecurityContextPersistenceFilter','logoutFilter',
'authenticationProcessingFilter','exceptionTranslationFilter', 'oauth2ProviderFilter', 'clientCredentialsTokenEndpointFilter',
'oauth2BasicAuthenticationFilter', 'securityContextHolderAwareRequestFilter',
'rememberMeAuthenticationFilter','anonymousAuthenticationFilter', 'oauth2ExceptionTranslationFilter', 'filterInvocationInterceptor'
]
grails.plugin.springsecurity.filterChain.chainMap = [
'/oauth/token': 'JOINED_FILTERS, -cookieSessionFilter, -oauth2ProviderFilter,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-exceptionTranslationFilter' ,
'/securedOAuth2Resources/**': 'JOINED_FILTERS,-cookieSessionFilter, -securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-oauth2BasicAuthenticationFilter,-exceptionTranslationFilter',
'/**': 'JOINED_FILTERS,-statelessSecurityContextPersistenceFilter,-oauth2ProviderFilter,-clientCredentialsTokenEndpointFilter,-oauth2BasicAuthenticationFilter,-oauth2ExceptionTranslationFilter'
]
Just proper ordering of filters seems to be solving the problem.
With this configuration I am able to generate the access_token.
I am new in creating a application in linkedin. Can some one help in getting the authorization??
I tried this code:
https://www.linkedin.com/uas/oauth2/authorization?response_type=code
&client_id=78lv1rv8ryh1hf
&scope=scope=r_fullprofile%20r_emailaddress%20r_network
&state=DCEEFWF45453sdffef424
&redirect_uri=http://www.mycoolsite.com
I am getting error saying that ...
error=unsupported_response_type&error_description=We+only+support+a+response_type+of+"code"%2C+but+you+passed+code+
There are a few things that can be improved:
you have not URL-encoded the redirect_uri parameter value
you're passing scope= in the scope value, which seems to be a typo/duplicate
you may have inserted a space/line-break in your URL since the following works for me:
https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=78lv1rv8ryh1hf&scope=r_fullprofile%20r_emailaddress%20r_network&state=DCEEFWF45453sdffef424&redirect_uri=http%3A%2F%2Fwww.mycoolsite.com
I've deployed MVC 5 site to AppHarbor, got the https-only app working thanks to this gist linked by AppHarbor support.
When I connected to Google OAuth 2 provider locally, everything worked fine - I can log in without problems, but when I try it on AppHarbor, I get error on login "redirect_uri_mismatch". I've got proper key and secret set for web app, the problem is with path, for some reason my page responds with redirect_uri starting with "http://..." instead of "https://..." which I've set in the google project console - (other than that it's the same uri).
I've tried this workaround for URL-based problems, but it doesn't seem to change anything.
As I don't think switching to http for /signin-google would be a good idea - how to fix it?
It's a few months later but I hope this will help someone. I had exactly the same problem with AppHarbor load balancers and loosing the "https" in the redirect_uri string. The simplest solution that I found is to register a few lines of code like a middleware in Startup.Auth.cs before any registration of external login providers:
app.Use(async (context, next) =>
{
if (string.Equals(context.Request.Headers["X-Forwarded-Proto"], "https", StringComparison.InvariantCultureIgnoreCase))
{
context.Request.Scheme = "https";
}
await next.Invoke();
});
This simple middleware checks for AppHarbor header "X-Forwarded-Proto" and if exist just add a correct Scheme property. If you look at the Katana's code correct Scheme property solve the problem:
...
string requestPrefix = Request.Scheme + "://" + Request.Host;
string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath;
...
I am trying to download the Google spreadsheet using download API version 3 ( v3 ). I am getting "java.lang.IllegalArgumentException: Trying to set foreign cookie" error message while downloading spreadsheet. I am tried by my google apps account which is authenticated by 2 legged oauth authentication process. Is there anyone facing this kind of problem ?
Here is the error stacktrace :
Servlet.service() for servlet action threw exception|java.lang.IllegalArgumentException: Trying to set foreign cookie
at com.google.gdata.client.http.GoogleGDataRequest$GoogleCookie.<init>(GoogleGDataRequest.java:166)
at com.google.gdata.client.http.GoogleGDataRequest$GoogleCookieHandler.put(GoogleGDataRequest.java:399)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:710)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1000)
at sun.net.www.protocol.http.HttpURLConnection.getHeaderFields(HttpURLConnection.java:2053)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getHeaderFields(HttpsURLConnectionImpl.java:263)
at com.google.gdata.client.http.HttpGDataRequest.isOAuthProxyErrorResponse(HttpGDataRequest.java:558)
at com.google.gdata.client.http.HttpGDataRequest.checkResponse(HttpGDataRequest.java:549)
at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:530)
at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:535)
Edit: This issue occurs only in one of our user's accounts using our App. Its working fine for all other users
I faced the same issue and was able to solve it by changing the url.
The URL I got directly from GDrive:
https://docs.google.com/spreadsheets/d/19Du6mgmzP94vxxHK5httgfK4dqgycQkBBLDq_6I5J7o/edit#gid=1472457471
Had to modify the above to:
https://spreadsheets.google.com/feeds/spreadsheets/**19Du6mgmzP94vxxHK5httgfK4dqgycQkBBLDq_6I5J7o
Hope this will help someone.
I get the service this way:
int GDATA_TIMEOUT = 10* 1000;
spreadsheetService = new SpreadsheetService("cellmaster.com.au-v0.2");
spreadsheetService.setHeader("Authorization", "Bearer " + accessToken);
spreadsheetService.setConnectTimeout(GDATA_TIMEOUT);
spreadsheetService.setReadTimeout(GDATA_TIMEOUT);
And include a retry loop because it does fail once in a while.