带有 adal-angular4 和刷新令牌的角形



我正在使用以下包在Angular应用程序中实现Azure AD身份验证:

https://www.npmjs.com/package/adal-angular4

10-20 分钟后,令牌过期。还有另一个线程讨论类似的东西,但我根本找不到有效的解决方案。老实说,在阅读这篇文章时,由于隐式流的性质,我什至不确定这是否可能。欢迎所有指针。

Angular 2 ADAL 令牌刷新,用于隐式流(使用"adal-angular4"(

我有我的身份验证重定向页面,Azure 在其中重定向到:

ngOnInit() {
this.adal.handleWindowCallback();
sessionStorage.setItem("adal.username",this.adal.userInfo.userName);
this.loginService.userLoggedIn(this.adal.userInfo.userName);
console.log("in authredirect. setting user in storage:"+this.adal.userInfo.userName);
var url = sessionStorage.getItem("adal.return.url");
console.log(url);
setTimeout(() => {
this._zone.run(
() => this.router.navigate([url])
);
}, 500);
} 

在我的应用程序中,我有以下内容:

providers: [
AdalService, 
AuthenticationGuard,
{ provide: HTTP_INTERCEPTORS, useClass: AuthenticationInterceptor, multi: true }

在我的应用程序组件的构造函数中:

this.adalService.init(environment.adalConfig);

我的身份验证保护:

export class AuthenticationGuard implements CanActivate {
constructor(private adal: AdalService, private route: ActivatedRoute) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (this.adal.userInfo.authenticated) {
return true;
}
console.log("Adal Login");
var url = state.url;
console.log(url);
sessionStorage.setItem("adal.return.url",url);
this.adal.login();
console.log('AuthGuard'+this.adal);
return false;
}
}

最后是我的app.routing.ts:

{
path: 'chartering',
loadChildren: './views/chartering/chartering.module#CharteringModule',
canActivate: [AuthenticationGuard]
},

你很幸运,我以前遇到过这个完全相同的问题,我花了几周时间才解决它。若要获取访问令牌和刷新令牌,需要使用Microsoft的 MSAL 库而不是 ADAL。如果不使用 MSAL,绝对无法刷新令牌。不过,Microsoft的 MSAL 库毫无用处。我专门为我的 Angular 应用程序从头开始编写了一个简化版本。我为你上传到了github。MsalService.ts. 希望你能利用它。

基本上,每当您需要身份验证令牌时,都可以使用msalService.acquireToken功能。如果未从该函数返回任何令牌,则应注销用户。使用msalService.loginmsalService.logout来登录或注销用户。

由于 CORS 限制,无法从应用程序的客户端请求访问令牌或刷新令牌。我在服务器上创建了端点来发出请求。

[HttpPost, Route("AccessToken")]
public async Task<HttpResponseMessage> GetAccessToken(AccessTokenRequest accessTokenRequest)
{
HttpClient httpClient = new HttpClient();
var content = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("client_id", "<insert_your_client_id>"),
new KeyValuePair<string, string>("code", accessTokenRequest.AuthorizationCode),
new KeyValuePair<string, string>("redirect_uri", RemoveHashFromUri(accessTokenRequest.RedirectUri)),
new KeyValuePair<string, string>("client_secret", "<insert_your_client_secret>"),
new KeyValuePair<string, string>("scope", accessTokenRequest.Scope)
};
var response = await httpClient.PostAsync($"https://login.microsoftonline.com/{your_tenant_id}/oauth2/v2.0/token", new FormUrlEncodedContent(content));
return response;
}
[HttpPost, Route("RefreshToken")]
public async Task<HttpResponseMessage> RefreshToken(AccessTokenRequest accessTokenRequest)
{
HttpClient httpClient = new HttpClient();
var content = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "refresh_token"),
new KeyValuePair<string, string>("client_id", "<insert_your_client_id>"),
new KeyValuePair<string, string>("refresh_token", accessTokenRequest.AuthorizationCode),
new KeyValuePair<string, string>("client_secret", "<insert_your_client_secret>"),
};
var response = await httpClient.PostAsync($"https://login.microsoftonline.com/{your_tenant_id}/oauth2/v2.0/token", new FormUrlEncodedContent(content));
return response;
}
private string RemoveHashFromUri(string redirectUri)
{
if (string.IsNullOrWhiteSpace(redirectUri))
{
return null;
}
if (redirectUri.Contains("#"))
{
return redirectUri.Substring(0, redirectUri.IndexOf("#"));
}
return redirectUri;
}
public class AccessTokenRequest
{
public string AuthorizationCode { get; set; }
public string RedirectUri { get; set; }
public string Scope { get; set; }
}

在应用程序组件的构造函数或 ngOnInit(( 中,当用户实际登录到 Microsoft 时,您需要此代码来处理回调。使用从 url 哈希中的Microsoft返回的令牌,可以获取访问令牌。

let authorizationCallback: IAuthorizationCallback = this.msalService.processAuthorizationCallback();
if (authorizationCallback.code) {
// call out to your server for an access token
this.resourceFactory.create("Auth/AccessToken").post({
authorizationCode: authorizationCallback.code,
redirectUri: this.msalService.getRedirectUrl(),
scope: this.msalService.getScopes()
}).then((json: any) => {
try {
this.msalService.cacheAuthentication(json);
} catch (error) {
// handle error
}
}).catch((error: any) => {
// handle error
});
} else if (authorizationCallback.error) {
// handle error. Check authorizationCallback.error and authorizationCallback.error_description
}

如果您有任何问题,请告诉我。

最新更新