/// <summary> /// Validates the token with custom logic. /// </summary> public static void Manual(IntrospectionTokenModel itm) { var jwt = new JwtSecurityToken(itm.AccessToken); IList <string> errors = new List <string>(); if (!VerifyIssuer(jwt.Issuer, itm.ServerAuthorityAddress)) { errors.Add($"Mismatch of issuer. Expected: {itm.ServerAuthorityAddress} but found : {jwt.Issuer}"); } var authTime = int.Parse(jwt.Claims.First(x => x.Type == "auth_time").Value).ToDateTimeFromEpoch(); if (jwt.ValidTo < DateTime.Now) { errors.Add($"The token is expired. exp : {jwt.ValidTo}"); } if (jwt.ValidTo.Subtract(authTime) != jwt.ValidTo.Subtract(jwt.ValidFrom)) { errors.Add($"The auth time of the token ({authTime} is not the same as nbf value : {jwt.ValidFrom}"); } if (jwt.ValidTo > DateTime.Now && jwt.ValidTo - jwt.ValidFrom != new TimeSpan(0, 0, itm.ExpireIn)) { errors.Add( $"The token should expire in : {itm.ExpireIn} seconds but it expires in {(jwt.ValidTo - jwt.ValidFrom).Seconds}"); } if (!jwt.Claims.First(x => x.Type == "sub").Value.Equals(itm.UserId)) { errors.Add( $"Expected value of the sub : {itm.UserId} but the token contained : {jwt.Claims.First(x => x.Type == "sub").Value}"); } if (jwt.Claims.Where(x => x.Type == "scope").All(y => y.Value != itm.ScopeName)) { errors.Add($"The token does not contain the expected scope: {itm.ScopeName}"); } if (!jwt.Claims.First(x => x.Type == "client_id").Value.Equals(itm.ClientId)) { errors.Add($"The token does not contain the expected client_id: {itm.ClientId}"); } if (errors.Count > 0) { Console.WriteLine(); Console.WriteLine("//////////////////////////////////////"); foreach (var error in errors) { Console.WriteLine(error); } Console.WriteLine("//////////////////////////////////////"); } else { Console.WriteLine("The token for the given scope is valid."); } }
/// <summary> /// Introspection of access token using Identity Server 4's Introspect Client to connect to the introspection endpoint. /// </summary> public static async Task <IntrospectionResponse> OfAccessToken(IntrospectionTokenModel itm) { var introspectionClient = new IntrospectionClient( itm.IntrospectionPath, itm.ScopeName, itm.ScopePassword ); return(await introspectionClient.SendAsync(new IntrospectionRequest { Token = itm.AccessToken })); }
/// <summary> /// Introspection of accesstoken using httpClient to connect to the introspection endpoint. /// </summary> public static async Task <IntrospectionResponse> OfAccessToken(IntrospectionTokenModel itm) { using (var httpClient = new HttpClient()) { httpClient.SetToken("Basic", GetAuthenticationString(itm.ScopeName, itm.ScopePassword)); var form = new FormUrlEncodedContent(new[] { new KeyValuePair <string, string>("token", itm.AccessToken) }); var response = await httpClient.PostAsync(itm.IntrospectionPath, form); var result = await response.Content.ReadAsStringAsync(); return(new IntrospectionResponse(result)); } }
/// <summary> /// Parses the arguments. /// </summary> /// <param name="args"></param> private static IntrospectionTokenModel ParseArgs(string[] args) { //&& !IsHttpsAddress(args[0]) var itm = new IntrospectionTokenModel(); if (ValidateIntrospectionPath(args[0])) { itm.ServerAuthorityAddress = args[0]; itm.IntrospectionPath = args[0] + "/connect/introspect"; } else { Console.WriteLine("Make sure that the serverAuthorityAddress is valid"); Environment.Exit(1); } itm.ScopeName = args[1]; itm.ScopePassword = args[2]; itm.AccessToken = args[3]; return(itm); }