How to create refresh_token in identity Server c#? Thank u - .net-core

i have access_token from CreateResponseAsync. Now i want create refresh_token, pls help me.
// validate request
var result = await _validator.ValidateAsync(parameters, userResult.user);
if (result.IsError)
{
return BadRequest("Request validation failed");
}
var request = result.ValidatedRequest;
var authorizeResponse = await _generator.CreateResponseAsync(request);
// create refresh token by IRefreshTokenService
var response = new LoginResponse()
{
code = authorizeResponse.Code,
id_token = authorizeResponse.IdentityToken,
access_token = authorizeResponse.AccessToken,
};

Related

API is sending no data when calling from another project & showing HTTP error 204

I have a method in an ASP.net API, which sends JWT token when it gets a Request with HTTP Get Method. On fiddler when I call this API, everything works fine; but when I call same API with another project (made in angular 8) I get HTTP 204 Error and no data.
In Angular Project I call this API on NgOnInit of my Component.
Here is code of API
[HttpGet("[action]")]
public string GetToken()
{
try
{
string key = "FIPL#321456222222222222222222222222222222222222222222222222222222222222222222"; //Secret key which will be used later during validation
var issuer = "http://localhost:1424/"; //normally this will be your site URL
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
//Create a List of Claims, Keep claims name short
var permClaims = new List<Claim>();
permClaims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()));
//permClaims.Add(new Claim("valid", "1"));
//permClaims.Add(new Claim("userid", "1"));
//permClaims.Add(new Claim("name", "bilal"));
//Create Security Token object by giving required parameters
var token = new JwtSecurityToken(issuer, //Issure
issuer, //Audience
permClaims,
expires: DateTime.Now.AddDays(1),
signingCredentials: credentials);
var jwt_token = new JwtSecurityTokenHandler().WriteToken(token);
enter image description here
return (String)jwt_token;
}
catch (Exception ex)
{
return (string)ex.Message ;
}
}
Here is code of angular where API is called.
ngOnInit() {
let obj = JSON.parse(localStorage.getItem("Auth"));
this.DepartmentModel._iBPNo = obj.BPNo;
this.DepartmentModel._iLoginNo = obj.LoginNo;
//Here I am Calling the API to get token
this.httpServices.get("http://localhost:52484/api/Token/gettoken/", null, (data) => {
alert(JSON.stringify(data));
localStorage.setItem("Token", JSON.stringify(data));
}, (error) => {
console.log(error);
});
if (JSON.parse(sessionStorage.getItem("PDEP"))) {
this.DeptNo = JSON.parse(sessionStorage.getItem("PDEP"));
this.LoadData();
}
}
Here is link to my fiddler Page Response.
You can try subscribing to an HTTP request directly :
this.httpServices.get("http://localhost:52484/api/Token/gettoken").subscribe((data) => {
alert(JSON.stringify(data));
localStorage.setItem("Token", JSON.stringify(data));
}, (error) => {
console.log(error);
});

How to use refresh token to get a new access token from identity server 4 with Xamarin.Forms client

How to use refresh_token to obtain a new access token from identity server in Xamarin.Forms client?
I followed tutorial https://sinclairinat0r.com/2018/12/09/secure-data-access-with-identityserver4-and-xamarin-forms and created xamarin forms mobile app with authentication on IS4. I set an access token lifetime to few minutes. After access token expires, as excepted, applciation is no more able to access authorized endpoints. I have an refresh_token but i dont't know how to use it to obtain a new access token from identity server.
Client specified in is4 configuration:
new Client()
{
ClientId = "xamarin-client",
ClientName = "Xamarin client",
AllowedGrantTypes = { "authorization_code" },
AllowedScopes = {"openid", "profile", "values-api" },
AllowAccessTokensViaBrowser = true,
AllowOfflineAccess = true,
AlwaysIncludeUserClaimsInIdToken = true,
RequirePkce = true,
RequireClientSecret = false,
RedirectUris = { "https://iglooidentityserver.azurewebsites.net/grants" },
AccessTokenLifetime = 180,
}
Authenticator i've used:
var oAuth = new OAuth2AuthenticatorEx(
"xamarin-client",
"offline_access values-api",
new Uri("https://iglooidentityserver.azurewebsites.net/connect/authorize"),
new Uri("https://iglooidentityserver.azurewebsites.net/grants"))
{
AccessTokenUrl = new Uri("https://iglooidentityserver.azurewebsites.net/connect/token"),
ShouldEncounterOnPageLoading = false,
};
var presenter = new OAuthLoginPresenter();
presenter.Completed += Presenter_Completed;
presenter.Login(oAuth);
I handled this problem in an old project as follows, hope this helps you.
public async Task<string> GetAccessToken()
{
if ((_authService.AuthAccessTokenExpireIn - DateTime.Now).TotalMinutes < 10) {
var authResponse = await GetRefreshTokenAsync(_authService.AuthRefreshToken);
_authService.AuthAccessToken = authResponse.AccessToken;
_authService.AuthRefreshToken = authResponse.RefreshToken;
_authService.AuthAccessTokenExpireIn = authResponse.ExpiresIn;
}
return _authService.AuthAccessToken;
}
public async Task<UserToken> GetRefreshTokenAsync(string currentRefreshToken)
{
string data = string.Format("grant_type=refresh_token&client_id={0}&client_secret={1}&refresh_token={2}", GlobalSetting.Instance.ClientId, GlobalSetting.Instance.ClientSecret, refreshToken);
var token = await PostAsync<UserToken>(_httpClient,
GlobalSetting.Instance.TokenEndpoint,
data);
return token;
}
public async Task<UserToken> PostAsync<UserToken>(HttpClient httpClient, string uri, object data)
{
var content = new StringContent(JsonConvert.SerializeObject(data));
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.PostAsync(uri, content);
await HandleResponse(response);
string serialized = await response.Content.ReadAsStringAsync();
UserToken result = await Task.Run(() => JsonConvert.DeserializeObject<UserToken>(serialized, _serializerSettings));
return result;
}

How to authorize user with taken token from IdentityServer?

I have created an IdentityServer project ( B ) with this configuration :
new Client
{
ClientId = "ro.client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "api1" }
}
And I have project B with it's custom login page, When the user enter his/her user & password, I send this info to project B's backend, and through this code I can get the token from identity server - project A:
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync(_configuration["App:Authority"]);
if (disco.IsError)
{
throw new System.Exception("get info from identity server is failed.");
}
var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "ro.client",
ClientSecret = "secret",
UserName = "bob",
Password = "Pass123$",
Scope = "api1"
});
var accessToken = tokenResponse.AccessToken;
Now what I want to achieve is that somehow I make this user authorized and save the token in cookie, So when this user call another action with authorize attribute, does not redirect him/her to login page.
How can I achieve this ?

can not login with flutter in graphql with python backend

i try to login in in graphql API in Django backend.i send the request and get the session ID from API but when i try to use that session ID in another post requests i get the access denied error. i think maybe flutter device can not stay login or post requests are just single use because try this function from postman and get true answer. so what should i do?
here is my login request:
static Future<String> Login(String user,String password) async {
var url = "my url";
var request = "mutation{logIn(username:${'"'+user+'"'}, password:${'"'+password+'"'}){result session error}}";
http.Response res = await http.post(url, body:{
"query": request
}) ; // post api call
Map login = json.decode(res.body);
print(res);
print(res.headers);
print(login);
var RawData = login['data']['logIn'];
if (RawData['result']){
return(RawData['session']);
}else{
return '';
}
}
and my check session request:
static Future<String> checkSession(String session) async {
var url = "my url";
print('session is here: '+ session);
http.Response res = await http.post(
url,
headers: {'sessionid':session},
body:{
"query":"mutation{checkSessionValidation{result,error}}"
},) ;
Map state = json.decode(res.body);
print(res.headers);
print('send validator :' + res.body);
var RawData = state['data'];
print("raw data is: "+RawData);
return RawData;
}

Login from Universal App to Web Api using Live Id

I'm trying to implement following functionality:
User signs in into Live Id account from Windows Phone 8.1 (or Universal) app.
App accesses Web Api that I develop with ASP.NET Web Api 2
In this Web Api I need to authenticate the user.
Later, I want to authenticate same user in web app
Here is what I'm doing, and it doesn't work.
In my Windows Phone App:
var authClient = new LiveAuthClient("http://myservice.cloudapp.net");
LiveLoginResult result = await authClient.LoginAsync(new string[] { "wl.signin" });
if (result.Status == LiveConnectSessionStatus.Connected)
{
connected = true;
var identity = await ConnectToApi(result.Session.AuthenticationToken);
Debug.WriteLine(identity);
}
And then
private async Task<string> ConnectToApi(string token)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://myservice.cloudapp.net/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
// HTTP GET
HttpResponseMessage response = await client.GetAsync("api/values");
if (response.IsSuccessStatusCode)
{
string result = await response.Content.ReadAsStringAsync();
return result;
}
else
return response.ReasonPhrase;
}
}
And then in my web api I have following
public void ConfigureAuth(IAppBuilder app)
{
app.UseMicrosoftAccountAuthentication(
clientId: "my client id",
clientSecret: "my secret");
}
I registered http://myservice.cloudapp.net as redirect url.
The problem is authentication doesn't work, web api actions do not recognize the user.
I got it totally wrong. First, I actually need to use app.UseJwtBearerAuthentication method. The example was found here http://code.lawrab.com/2014/01/securing-webapi-with-live-id.html. But when I tried, I got this error in the output
IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 1,
Clause[0] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause
)
This one took me a while to figure out, until I found this post: JwtSecurityTokenHandler 4.0.0 Breaking Changes?
Putting these things together, I got the solution that seems to work now in my testing environment:
public void ConfigureAuth(IAppBuilder app)
{
var sha256 = new SHA256Managed();
var sKey = "<Secret key>" + "JWTSig";
var secretBytes = new UTF8Encoding(true, true).GetBytes(sKey);
var signingKey = sha256.ComputeHash(secretBytes);
var securityKeyProvider = new SymmetricKeyIssuerSecurityTokenProvider("urn:windows:liveid", signingKey);
var securityKey = securityKeyProvider.SecurityTokens.First().SecurityKeys.First();
var jwtOptions = new JwtBearerAuthenticationOptions()
{
//AllowedAudiences = new[] { "<url>" },
//IssuerSecurityTokenProviders = new[]
//{
// new SymmetricKeyIssuerSecurityTokenProvider("urn:windows:liveid",signingKey)
//},
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters()
{
IssuerSigningKeyResolver = (token, securityToken, keyIdentifier, validationParameters) =>
{
return securityKey;
},
ValidAudience = "<url>",
ValidIssuer = securityKeyProvider.Issuer
}
};
app.UseJwtBearerAuthentication(jwtOptions);
}
For anybody looking to do this from JavaScript I managed to get this working by following steps from this blog. You can find the audience by putting your token through jwt.io
https://blog.dirk-eisenberg.de/2014/08/30/validate-authentication_token-from-microsoft-liveid-with-node-express-jwt/
const validateLiveJWT = (token) => {
const secret = '<<SECRET>>';
const sha256 = crypto.createHash('sha256');
sha256.update(secret + 'JWTSig', 'utf8');
const secretBase64 = sha256.digest('base64');
const secret = new Buffer(secretBase64, 'base64');
const options = {
audience: '<<AUDIENCE>>',
issuer: 'urn:windows:liveid',
};
return new Promise((resolve) => {
jwt.verify(token, secret, options, (err: any, claims: any) => {
if (err) {
resolve(undefined);
} else {
resolve(claims);
}
});
});
}

Resources