Implementing ROPC based authentication in asp .net core - asp.net

I'm trying to implement ROPC flow in asp.net api . Can you please guide me on how to achieve this properly in ASP.net core using built in authentication library. If it is not possible what are the alternatives
I'm able to get the access token using http call to azure AD token endpoint. But i'm not able to validate the token using built in authentication library
can we implement this without the HTTP call , but using built in library.
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
Im using the below code snippet to get the access token
private async Task<string> GetTokenAsync(string username, string password)
{
string grantType = "password";
string tenantId = Configuration["AzureAdNative:TenantId"];
string clientId = Configuration["AzureAdNative:ClientId"];
string resource = Configuration["AzureAdNative:Resource"];
string endpoint = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var dict = new Dictionary<string, string>();
dict.Add("grant_type", grantType);
dict.Add("client_id", clientId);
dict.Add("username", username);
dict.Add("password", password);
dict.Add("resource", resource);
var req = new HttpRequestMessage(HttpMethod.Post, endpoint) { Content = new FormUrlEncodedContent(dict) };
var res = await client.SendAsync(req);
string result = res.Content.ReadAsStringAsync().Result;
var jwt = JObject.Parse(result);
return result;
// return jwt.GetValue("access_token").ToString();
}
getting unauthorised 401 error while validating with above code. access token is being sent in the authorization header (eg: Authorization : Bearer e4dgkddskdsdk).

Related

How to get Authorization_code and access_Token and send envelope DocuSign using asp.net

I am trying to send envelope using docuSign, but having error while get authorization_code which need to get access_Token.
Please help me to get authorization_Code and access_Token.
I am using ASP.Net web forms and .NET framework 4.5.2
DocuSign.eSign.dll 5.2.0
DocuSign.Integration.Client.dll 1.7.2
Request:
https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature&client_id=4f464e25-6425-4ea6-915b-aa9bac5b8ce7&redirect_uri=https://account-d.docusign.com/ds/login?authType=JWT
Response:
The redirect redirect_uri is not registered properly with DocuSign
string RedirectURI = "https://account-d.docusign.com/ds/login?authType=JWT";
string ClientSecret = "****";
string IntegratorKey = "****";
Uri oauthLoginUrl = GetAuthorizationUri(IntegratorKey, scopes, RedirectURI, OAuth.CODE, null);
WebRequest request = WebRequest.Create(oauthLoginUrl);
WebResponse response = request.GetResponse();
public Uri GetAuthorizationUri(string clientId, List<string> scopes, string redirectUri, string responseType, string state = null)
{
string formattedScopes = (scopes == null || scopes.Count < 1) ? "" : scopes[0];
StringBuilder scopesSb = new StringBuilder(formattedScopes);
for (int i = 1; i < scopes.Count; i++)
{
scopesSb.Append("%20" + scopes[i]);
}
UriBuilder builder = new UriBuilder("https://account-d.docusign.com")
{
Scheme = "https",
Path = "/oauth/auth",
Port = 443,
Query = BuildQueryString(clientId, scopesSb.ToString(), redirectUri, responseType, state)
};
return builder.Uri;
}
Please make sure that the specified redirect URI is configured under the redirect URI section for the integration key that is being used. Please keep in mind that the same exact redirect URI has to be used when using your authentication URL.
The specified section is found under Settings > Apps and Keys > Click on your integration key > Edit
I would also recommend creating a new integration key, since you have shared it publicly on this thread.

Implement Microsoft Graph API in a .netcore API project

I am trying to write a .netcore API which gets a bearer token from third party Webapp. This .netcore API should access the Microsoft graph API and get the user group information back from Azure AD.
I was following the sample project https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore.
But unfortunately this uses AAD graph rather tha Microsoft graph API.
I tried to implement Graph API in the .netcore api project in the above sample.
Things I have tried
I have changed the AAD graph to Graph API in the AzureAdAuthenticationBuilderExtensions.cs(in the web app project)
options.Resource = "https://graph.microsoft.com";
Also I used the Microsoft.Graph nuget in the API project. And I am trying to create the GraphServiceClient using the code below
public GraphServiceClient GetClient(string accessToken, IHttpProvider provider = null)
{
var words = accessToken.Split(' ');
var token = words[1];
var delegateAuthProvider = new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
return Task.FromResult(0);
});
var graphClient = new GraphServiceClient(delegateAuthProvider, provider ?? new HttpProvider());
return graphClient;
}
And finally I am trying to access the user information using the code below,
public async Task<IEnumerable<Group>> GetGroupAsync(string accessToken)
{
var graphClient = GetClient(accessToken);
try
{
User me = await graphClient.Me.Request().GetAsync();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
var user= await graphClient.Users["***"].Request().Expand("MemberOf").GetAsync();
var userEmail = "testemail#test.com";
var usergroup = await graphClient.Users[userEmail].GetMemberGroups(false).Request().PostAsync();
var groupList = new List<Group>();
foreach (var g in usergroup.CurrentPage)
{
var groupObject = await graphClient.Groups[g].Request().GetAsync();
groupList.Add(groupObject);
}
return groupList;
}
But when I try the code I am getting the error "Microsoft.Graph.ServiceException: Code: InvalidAuthenticationToken
Message: Access token validation failure.Inner error at Microsoft.Graph.HttpProvider."
Can somebody help me please?
Thanks in advance
The access token passed to GetGroupAsync is not correct , and i am confused why you need to split the token :
var words = accessToken.Split(' ');
var token = words[1];
But never mind , since you have modified options.Resource = "https://graph.microsoft.com"; ADAL will help you get access token for Microsoft Graph API in OnAuthorizationCodeReceived function , and save the tokens to cache .
To get the access token , you could use ADAL to get the token from cache :
AuthenticationResult result = null;
// Because we signed-in already in the WebApp, the userObjectId is know
string userObjectID = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
// Using ADAL.Net, get a bearer token to access the TodoListService
AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.Authority, new NaiveSessionCache(userObjectID, HttpContext.Session));
ClientCredential credential = new ClientCredential(AzureAdOptions.Settings.ClientId, AzureAdOptions.Settings.ClientSecret);
result = await authContext.AcquireTokenSilentAsync("https://graph.microsoft.com", credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
Then you could pass that token to your function:
await GetGroupAsync(result.AccessToken);
Modify your GetClient function to delete the split part:
public GraphServiceClient GetClient(string accessToken, IHttpProvider provider = null)
{
var delegateAuthProvider = new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
});
var graphClient = new GraphServiceClient(delegateAuthProvider, provider ?? new HttpProvider());
return graphClient;
}

HttpResponseMessage asp.net : How to integrate basic authentication

How do I implement a basic authentication filter into a working web api client written in asp.net HttpResponseMessage.
How do I check the authentication (user:pass or 64Base Key) and if failed pass unauthorised message.
This is my current code and it work:
public HttpResponseMessage WebAPiPost([FromBody]byte[] incomingData)
{
string rawData = getRawPostData().Result;
var responseMessage= (HttpResponseMessage)null;
responseMessage = new HttpResponseMessage()
{Content = new StringContent(SQLFunctions.SQLStoredProcedureJson("StoredProcedureName", rawData, true), System.Text.Encoding.UTF8, "application/json")};
return responseMessage;
}

ASP.NET Boilerplate Auth from Windows Phone 8.1 - bearer token

I'm using asp.net boilerplate for my website. There I have standard authentication from aspnetboilerplate/module-zero(OWIN).
But now I need athentication for my windows phone app(wp8.1)
I was trying configure my application for authorization with bearer but I failed..
How configurate asp.net boilerplate application for my windows phone app auth?
In windows phone app I send post to my web api like this:
public static async Task<TokenResponseModel> GetBearerToken(string siteUrl, string Username, string Password)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(siteUrl);
client.DefaultRequestHeaders.Accept.Clear();
HttpContent requestContent = new StringContent("grant_type=password&username=" + Username + "&password=" + Password, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage responseMessage = await client.PostAsync("Token", requestContent);
if (responseMessage.IsSuccessStatusCode)
{
string jsonMessage;
using (Stream responseStream = await responseMessage.Content.ReadAsStreamAsync())
{
jsonMessage = new StreamReader(responseStream).ReadToEnd();
}
TokenResponseModel tokenResponse = (TokenResponseModel)JsonConvert.DeserializeObject(jsonMessage, typeof(TokenResponseModel));
return tokenResponse;
}
else
{
return null;
}
}
But what should I do in WebApi? How auth and next response bearer and how auth in next step using bearer when on class i have [AbpAuthorize]?
This now documented and implemented in module zero template
code:
In module WebApi:
Configuration.Modules.AbpWebApi().HttpConfiguration.Filters.Add(new HostAuthenticationFilter("Bearer"));
In controller WebApi:
[HttpPost]
public async Task<AjaxResponse> Authenticate(LoginModel loginModel)
{
CheckModelState();
var loginResult = await GetLoginResultAsync(
loginModel.UsernameOrEmailAddress,
loginModel.Password,
loginModel.TenancyName
);
var ticket = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties());
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
return new AjaxResponse(OAuthBearerOptions.AccessTokenFormat.Protect(ticket));
}
documentation: http://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template#token-based-authentication

Web API Individual Accounts Register User

I am developing a ASP.NET Web API using ASP.NET Identity (Individual Accounts) for authentication/authorization. I am able to successfully login by making a call to /token URI.
All I want is to automatically sign in my user when he register himself to my application. I am able to do the half of the task by signing in the user in Register method using following code:
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
Is there a way I can return the same OAuth like response which I get when I make successful call to /token. Some thing like following:
{"access_token":"access-token","token_type":"bearer","expires_in":1209599,"userName":"username",".issued":"Sat, 22 Mar 2014 08:12:14 GMT",".expires":"Sat, 05 Apr 2014 08:12:14 GMT"}
Actually I'm facing same issue moments ago, I handled it in such an ugly way-- Inside Register method, I made another web request to access "/token", just after created the new user, and pass the latest username and password.
private string GetTokenForNewUser(string username, string password)
{
using (var client = new HttpClient())
{
var host = Request.RequestUri.Scheme + "://" + Request.RequestUri.Host + ":" + Request.RequestUri.Port;
client.BaseAddress = new Uri(host);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Dictionary<string, string> credential = new Dictionary<string, string>();
credential.Add("grant_type", "password");
credential.Add("username", username);
credential.Add("password", password);
HttpResponseMessage response = client.PostAsync(host + "token", new FormUrlEncodedContent(credential)).Result;
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsStringAsync().Result;
}
}
//if we go this far, something error happens
return string.Empty;
}
I don't think this is a good way to do so, but it just works.
You can add payload for the token (it also depends on the token you are using). Then, you can also retrieve the payload value from the token during request.
var token = new JwtSecurityToken(_config["Jwt:Issuer"], _config["Jwt:Issuer"], signingCredentials: credentials, expires: DateTime.Now.AddDays(2));
token.Payload["UserId"] = user.Id;

Resources