2016-09-29 5 views
1

私たちがハイブリッド・フローを使用してクライアントからログインし、暗黙のフローを使用して別のクライアントからログインしようとすると、IdentityServer3サービスが奇妙な動作をします。第2のユーザは、STSが認可を認識できず、ユーザをログインページに繰り返し戻すループに詰め込まれる。この動作を再現し、ログファイルで確認することができます。また、最初にログオンしたクライアントは正常にログインできますが、2番目のクライアントはループでスタックします。 IdentityServer3のフックを使用してカスタムログインプロセスを実装しました。ここで異なるフローを使用するクライアントのIdentityServer3ログイン・ループ

public class EmsUserService : UserServiceBase 
{ 
    private IEmsEntities _context 
    { 
     get 
     { 
      var container = DependencyResolver.Current; 
      var service = container.GetService<IEmsEntities>(); 
      service.ChangeReadUncommittedSetting(true); 
      return service; 


     } 
    } 

    public override Task PreAuthenticateAsync(PreAuthenticationContext context) 
    { 
     var request = HttpContext.Current.Request; 
     if (HttpContext.Current.Request.IsAuthenticated) 
     { 
      var personId = HttpContext.Current.User.Identity.Name; 
      var user = _context.Person.Include(p => p.PersonLogin).First(x => x.PersonId.ToString() == personId); 

      context.AuthenticateResult = new AuthenticateResult(personId, user.PersonLogin.LoginName); 
     } 

     return Task.FromResult(0); 
    } 


    public override Task AuthenticateLocalAsync(LocalAuthenticationContext context) 
    { 
     var password = context.Password; 
     var encryptPassword = Password.Encrypt(password); 

     var allUserLoginRecords = Utilities.GetUserLoginRecords(_context, encryptPassword, context.UserName); 

     //We want to make sure that we recognize if a user already exists but is locked out. "Locked out" is determined by a username/password 
     //that matches but is not currently active 
     if (allUserLoginRecords.Any()) 
     { 
      if (allUserLoginRecords.Any(u => u.PersonLogin.IsActive)) 
      { 
       var active = allUserLoginRecords.First(u => u.PersonLogin.IsActive); 
       var isOld = Utilities.IsOld(active.PersonLogin); 
       var isComplex = Utilities.IsComplex(context.Password); 
       var resetRequired = active.PersonLogin.IsResetRequired; 


       if (isOld || !isComplex || resetRequired) 
       { 
        context.AuthenticateResult = new AuthenticateResult(String.Format("~/ChangePassword/{0}", isOld), 
         active.PersonId.ToString(), 
         active.PersonLogin.LoginName); 
       } 
       else 
       { 
        context.AuthenticateResult = new AuthenticateResult(active.PersonId.ToString(), 
         active.PersonLogin.LoginName); 
       } 
      } 


      else 
      { 
       context.AuthenticateResult = 
        new AuthenticateResult(
         "This account has been locked. Please contact OSPI Customer Support to re-activate it."); 
      } 
     } 

     else 
     { 
      context.AuthenticateResult = 
       new AuthenticateResult(
        "The username and password combination does not match. Your username must be an email address and the password is case-sensitive."); 
     } 
     return Task.FromResult(0); 
    } 




    public override Task GetProfileDataAsync(ProfileDataRequestContext context) 
    { 
     var claims = new List<Claim>(); 
     var subjectId = context.Subject.GetSubjectId(); 



     // issue the claims for the users 
     var user = _context.Person.Include(p => p.PersonLogin).First(x => x.PersonId.ToString() == subjectId && x.PersonLogin.IsActive); 
     if (user != null) 
     { 
      var emailClaim = new Claim(ClaimTypes.Email, user.PersonLogin.LoginName); 
      claims.Add(emailClaim); 
      var nameClaim = new Claim(ClaimTypes.Name, user.PersonId.ToString()); 
      claims.Add(nameClaim); 
      context.IssuedClaims = claims; 
     } 

     return Task.FromResult(0); 
    } 



    public override Task IsActiveAsync(IsActiveContext context) 
    { 
     var subjectId = context.Subject.GetSubjectId(); 

     // Look up the user to make sure that they're active 
     var user = _context.Person.Include(p => p.PersonLogin).First(x => x.PersonId.ToString() == subjectId && x.PersonLogin.IsActive); 
     if (user == null) 
     { 
      context.IsActive = false; 
      return Task.FromResult(0); 
     } 

     context.IsActive = true; 
     return Task.FromResult(0); 
    } 
} 

IdentityServerログがログインしようとしている2番目のクライアントのためのものです:あなたは、私がログインにリダイレクトされていていることがわかります

> w3wp.exe Information: 0 : 2016-09-29 10:07:08.008 -07:00 [Information] User is not authenticated. Redirecting to login. 
w3wp.exe Information: 0 : 2016-09-29 10:07:08.009 -07:00 [Information] End authorize request 
w3wp.exe Information: 0 : 2016-09-29 10:07:08.010 -07:00 [Information] Redirecting to login page 
2016-09-29 10:07:08.011 -07:00 [Debug] Protecting message: "{\"ReturnUrl\":\"https://localhost/OspiSts/identity/connect/authorize?client_id=.....&redirect_uri=......&response_mode=form_post&response_type=code%20id_token%20token&scope=openid%20profile%20authApi&state=OpenIdConnect.AuthenticationProperties%.....\",\"ClientId\":\"....",\"AcrValues\":[],\"Created\":636107656279778454}" 
w3wp.exe Information: 0 : 2016-09-29 10:07:08.018 -07:00 [Information] Login page requested 
2016-09-29 10:07:08.019 -07:00 [Debug] signin message passed to login: "{ 
    \"ReturnUrl\": \"......", 
    \"ClientId\": \"...", 
    \"IdP\": null, 
    \"Tenant\": null, 
    \"LoginHint\": null, 
    \"DisplayMode\": null, 
    \"UiLocales\": null, 
    \"AcrValues\": [], 
    \"Created\": 636107656279778454 
}" 
w3wp.exe Information: 0 : 2016-09-29 10:07:12.847 -07:00 [Information] rendering login page 
w3wp.exe Information: 0 : 2016-09-29 10:07:21.148 -07:00 [Information] Login page submitted 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.417 -07:00 [Information] Login credentials successfully validated by user service 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.419 -07:00 [Information] { 
    "Category": "Authentication", 
    "Name": "Local Login Success", 
    "EventType": "Success", 
    "Id": 1010, 
    "Details": { 
    "LoginUserName": "...", 
    "SignInId": "...", 
    "SignInMessage": { 
     "ReturnUrl": "....", 
     "ClientId": "...", 
     "AcrValues": [], 
     "Created": 636107656279778454 
    }, 
    "PartialLogin": false, 
    "SubjectId": "141480", 
    "Name": "..." 
    }, 
    "Context": { 
    "ActivityId": "77206837-cc1c-475b-a3e0-9b362b9dad29", 
    "TimeStamp": "2016-09-29T17:07:27.4199277+00:00", 
    "ProcessId": 1712, 
    "MachineName": "WKS-C070421", 
    "RemoteIpAddress": "::1" 
    } 
} 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.421 -07:00 [Information] Calling PostAuthenticateAsync on the user service 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.425 -07:00 [Information] issuing primary signin cookie 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.428 -07:00 [Information] redirecting to: .... 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.442 -07:00 [Information] Start authorize request 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.443 -07:00 [Information] Start authorize request protocol validation 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.479 -07:00 [Information] "Authorize request validation success" 
"{ 
    \"ClientId\": \"...", 
    \"ClientName\": \"Data Quality\", 
    \"RedirectUri\": \"...", 
    \"AllowedRedirectUris\": [ 
    \"...", 
    \"....", 
    \"....", 
    \"...." 
    ], 
    \"SubjectId\": \"unknown\", 
    \"ResponseType\": \"code id_token token\", 
    \"ResponseMode\": \"form_post\", 
    \"Flow\": \"Hybrid\", 
    \"RequestedScopes\": \"openid profile authApi\", 
    \"State\": \"OpenIdConnect.AuthenticationProperties=....", 
    \"Nonce\": \"..", 
    \"Raw\": { 
    \"client_id\": \"...", 
    \"redirect_uri\": \"...", 
    \"response_mode\": \"form_post\", 
    \"response_type\": \"code id_token token\", 
    \"scope\": \"openid profile authApi\", 
    \"state\": \"OpenIdConnect.AuthenticationProperties=...", 
    \"nonce\": \"..." 
    } 
}" 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.480 -07:00 [Information] User is not authenticated. Redirecting to login. 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.481 -07:00 [Information] End authorize request 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.483 -07:00 [Information] Redirecting to login page 
2016-09-29 10:07:27.484 -07:00 [Debug] Protecting message: "{\"ReturnUrl\":\"..",\"ClientId\":\"...",\"AcrValues\":[],\"Created\":636107656474419255}" 
w3wp.exe Information: 0 : 2016-09-29 10:07:27.493 -07:00 [Information] Login page requested 
2016-09-29 10:07:27.495 -07:00 [Debug] signin message passed to login: "{ 
    \"ReturnUrl\": \"...", 
    \"ClientId\": \"...", 
    \"IdP\": null, 
    \"Tenant\": null, 
    \"LoginHint\": null, 
    \"DisplayMode\": null, 
    \"UiLocales\": null, 
    \"AcrValues\": [], 
    \"Created\": 636107656474419255 
}" 
w3wp.exe Information: 0 : 2016-09-29 10:07:28.657 -07:00 [Information] rendering login page 

、私は、ログイン下記のログインプロセスのためのコードがありますSTSは認証を認識できません。これは、どちらのクライアントであろうと、第2のクライアントがログインするときに発生します。

ご協力いただきありがとうございます。

答えて

0

System.WebのMicrosoft Owin実装にバグがあります。 IIS上でOwinアプリケーションを実行するときに使用されているもの。 ASP.NET MVC5で新しいOwinベースの認証処理を使用している場合は、おそらく99%のユーザーがこれを実行します。

Owinによって設定されたクッキーが不思議にいくつか消えてしまいます。

このミドルウェアは、このバグに対する修正です。 Cookieを処理するミドルウェアの前にSimpleを追加すると、認証Cookieが保持されます。ここにリンクがあります

https://github.com/KentorIT/owin-cookie-saver

関連する問題