2015-05-29 2 views
4

У меня есть приложение Asp.Net MVC с большим количеством вызовов javascript. Я защитил действие MVC, перенаправляюсь на сервер идентификации, логин, а затем перенаправляюсь обратно клиенту. Я могу совершать последующие вызовы через MVC, но как мне получить этот токен доступа и использовать его в вызовах ajax?Как передать токен доступа через javascript с помощью IdentityServer3?

Вот мой Startup.cs файл:

public void Configuration(IAppBuilder app) 
{ 
    // Tell Microsoft to not try to map to .Net's ClaimsTypes 
    JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); 

    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = "Cookies" 
    }); 

    const string svcUrl = "https://localhost/svc.security"; 

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions 
    { 
     Authority = svcUrl, 
     ClientId = "nedd_client", 
     RedirectUri = "http://localhost:61207/", 
     ResponseType = "code id_token token", 

     // Ask for 'roles' claims & for access to web services 
     Scope = "openid profile", 

     SignInAsAuthenticationType = "Cookies", 

     Notifications = new OpenIdConnectAuthenticationNotifications 
     { 
      AuthorizationCodeReceived = async n => 
      { 
       // filter "protocol" claims 
       var claims = new List<Claim>(from c in n.AuthenticationTicket.Identity.Claims 
              where c.Type != "iss" && 
                c.Type != "aud" && 
                c.Type != "nbf" && 
                c.Type != "exp" && 
                c.Type != "iat" && 
                c.Type != "nonce" && 
                c.Type != "c_hash" && 
                c.Type != "at_hash" 
              select c); 

       // Get userinfo data 
       var userInfoClient = new UserInfoClient(new Uri(svcUrl + "/connect/userinfo"), n.ProtocolMessage.AccessToken); 

       var userInfo = await userInfoClient.GetAsync(); 
       userInfo.Claims.ToList().ForEach(ui => claims.Add(new Claim(ui.Item1, ui.Item2))); 

       // Get access token 
       var tokenClient = new OAuth2Client(new Uri(svcUrl + "/connect/token"), "nedd_client", "secret"); 

       var response = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri); 

       claims.Add(new Claim("access_token", response.AccessToken)); 
       claims.Add(new Claim("expires_at", DateTime.Now.AddSeconds(response.ExpiresIn).ToLocalTime().ToString())); 
       claims.Add(new Claim("id_token", n.ProtocolMessage.IdToken)); 

       n.AuthenticationTicket = new AuthenticationTicket(new ClaimsIdentity(claims.Distinct(new ClaimComparer()), n.AuthenticationTicket.Identity.AuthenticationType), n.AuthenticationTicket.Properties); 
      }, 
     } 

    }); 

} 

А вот пример Ajax вызова:

$.ajax({ 
    type: 'GET', 
    url: "https://localhost/svc.security/connect/userinfo", 
    //headers: { "Authorization": "Bearer " + my.getAccessToken() }, // get access token from cookie? 

}).done(function (data, textStatus, jqXHR) { 
    show(JSON.parse(jqXHR.response));  
+0

Не можете ли вы просто сохранить токен доступа в локальном хранилище в веб-браузере? Токен доступа не должен храниться в секрете. Если это подделано тем фактом, что оно подписано, это не позволит его принять. – webworm

ответ

1

Я думаю, что после входа в систему успешно, вы должны держать маркер где- (в печенье, например,), тогда ваш «my.getAccessToken()» должен прочитать оттуда.

Этот пример делает аналогичный https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/Clients/JavaScriptImplicitClient/index.html

if (window.location.hash) { 
     handleCallback(); 
    } 
+0

Haz, который отлично работает для чистого приложения javascript, но не работает с миром MVC и ajax. Я понял это и разместил свой собственный ответ ниже. –

+0

Поймите свое исправление. Он работает, но должен быть улучшен с точки зрения эффективности, поскольку перед каждым основным запросом необходим дополнительный запрос. Извините, я не могу прокомментировать ваш ответ из-за моих «баллов»;) – hazjack

2

я понял, что моя реальная проблема заключалась в том, что, после входа в систему, печенье было печенье ASP.Net сервер и не доступны для клиента.

Я добавил метод для моего MVC-контроллера для javascript, чтобы получить токен, который уже был у сервера.

[Authorize] 
    public ActionResult GetAccessToken() 
    { 
     var token = (System.Web.HttpContext.Current.User.Identity as ClaimsIdentity).FindFirst("access_token"); 
     if (token != null) 
     { 
      return Content(token.Value); 
     } 

     return Content(""); 
    } 

Тогда мой Javascript будет выглядеть примерно так, назвав его, чтобы получить маркер, прежде чем сделать Ajax вызов веб-службы.

function getAccessToken() { 
    var returnVal = ""; 

    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", "http://localhost:61207/Home/GetAccessToken", false); 
    xhr.send(); 
    returnVal = xhr.responseText; 

    return returnVal; 
} 

Там может быть другое решение, которое является более элегантным, но как только я имел в виду, очевидно, что было доступно на клиенте и сервере, это, казалось, самое лучшее решение.

Смежные вопросы