问题
I am working on an existing, in-production Angular 7 application. My task is migrate from a local authentication scheme to an existing company-wide identity provider. The identity provider is compliant with OAuth2. I am using the oidc-client library to try and accomplish this.
The Angular app is using HashLocationStrategy, and I am fairly certain this requirement cannot change. I was not the original author of this app, so I don’t know the exact reasoning for choosing HashLocationStrategy over the default PathLocationStrategy. Right now, I would rather not go down the rabbit hole of changing to PathLocationStrategy. I might be asking for more trouble.
The identity provider will not allow a hash character in the redirect URI as stated in the OAuth 2.0 spec here: https://tools.ietf.org/html/rfc6749#section-3.1.2 (“The endpoint URI MUST NOT include a fragment component.”).
For development, I want the redirect URI after successful login to be "http://localhost:8080/#/dashboard", but due to the above restriction, I cannot do this. The developers who own the identity provider API have told me to encode the hash character in the redirect URI, like so: "http://localhost:8080/%23/dashboard". I have tried this, but when my application encounters the redirect, it does not decode it and therefore I get this error:
Cannot GET /%23/dashboard
The post-login redirect URL returned to the app from the identity provider looks like this:
http://localhost:8080/%23/dashboard?code=7d25a8af920d219631a15019fc243ca2&state=9821f4153a1b45d3b6ed9a6813bd70c9&session_state=5c59c99f31156aa805b7267f82b0aa8e499d3f81cf5caab0335595c6e397bbf8.8_QJpOLj75eOfarD091Snw
My authservice’s login function looks like this, in order to invoke the login page:
login() {
const idSettings = {
scope: 'openid',
response_type: 'code',
authority: this.baseUrl,
client_id: this.clientId,
redirect_uri: 'http://localhost:8080/%23/dashboard', // This is what the ID provider will allow.
};
this.userManager = new UserManager(idSettings); // oidc-client UserManager
return this.userManager.signinRedirect();
}
My question is: is there an event I can listen for within the Angular app to capture and decode the post-login redirect URL prior to attempting to route there? If so, I can just convert %23 to # and continue with the redirect.
Or, alternately, is there a way I can temporarily suspend the use of HashLocationStrategy for this one route? If this were possible, I might be able to use “http://localhost:8080/dashboard” for my redirect URI, and still get it to route to the correct component.
I have been looking online but so far all Angular examples that I have seen are using PathLocationStrategy instead of HashLocationStrategy.
I have also searched here and have not discovered a question exactly like mine. So I don’t think this is a duplicate question.
Thanks for any advice.
UPDATE: For what it's worth, I was never able to resolve this issue, except by changing the app from using HashLocationStrategy to using PathLocationStrategy. So, that's what I did. I did some more research into our source-control and discovered who and when the change to HashLocationStrategy was done, and based on that I am guessing that the original author didn't realize that some configuration on the web server was necessary to support PathLocationStrategy, and that (hopefully) is the only reason he chose to use HashLocationStrategy. We are using webpack dev-server for our development (localhost) web servers, so it was a relatively simple matter to add "historyApiFallback: true" to the webpack.config.js in order to support reloading the same URL. When I get access to our staging and production servers that use nginx, I hope to make similar config changes.
来源:https://stackoverflow.com/questions/59686996/angular-application-cant-redirect-after-oauth2-login-when-using-hashlocationstr