Xamarin Mobile with IdentityServer 3 - xamarin

I am trying to establish a secure connection for my mobile app using Identity server 3 and Xamarin. I have a web app that works perfectly using the identity server but can’t for the life of me get it working with mobile. I have it asking for credentials, logging in and getting an access token. However when I try to make a call using the token I still get HttpContext.User.Identity.IsAuthenticated as false and the call fails.
I created a new client in the identity server for the mobile app and have it as the following:
new IdentityServer3.Core.Models.Client
{
Enabled = true,
ClientName = "MyMobile Mobile App",
ClientId = "myMobile",
ClientSecrets = { new Secret("myMobileSecret".Sha256()) },
Flow = Flows.Hybrid,
RedirectUris = new List<string>
{
…
},
PostLogoutRedirectUris = new List<string>
{
…
},
RequireConsent = false,
AllowAccessToAllScopes = true,
RequireSignOutPrompt = false
}
My code is as follows:
var authorizeRequest = new AuthorizeRequest(GlobalSetting.Instance.IdentityEndpoint);
var dic = new Dictionary<string, string>();
dic.Add("client_id", GlobalSetting.Instance.ClientId);
dic.Add("client_secret", GlobalSetting.Instance.ClientSecret);
dic.Add("response_type", "code token");
dic.Add("scope", "openid profile roles");
dic.Add("redirect_uri", GlobalSetting.Instance.IdentityCallback);
dic.Add("nonce", Guid.NewGuid().ToString("N"));
_currentCSRFToken = Guid.NewGuid().ToString("N");
dic.Add("state", _currentCSRFToken);
var authorizeUri = authorizeRequest.Create(dic);
LoginWebView.Source = authorizeUri;
On response…
private async Task NavigateAsync(string url)
{
var unescapedUrl = System.Net.WebUtility.UrlDecode(url);
if (unescapedUrl.StartsWith(GlobalSetting.Instance.IdentityCallback))
{
LoginWebView.IsVisible = false;
var authResponse = new AuthorizeResponse(url);
if (!string.IsNullOrWhiteSpace(authResponse.Code))
{
var userToken = await _identityService.GetTokenAsync(authResponse.Code);
string accessToken = userToken.AccessToken;
if (!string.IsNullOrWhiteSpace(accessToken))
{
Authorization.AccessToken = accessToken;
Authorization.IdToken = authResponse.IdentityToken;
Application.Current.MainPage = _homePage;
}
}
}
…
}
public async Task<UserToken> GetTokenAsync(string code)
{
string data = string.Format("grant_type=authorization_code&code={0}&redirect_uri={1}&code_verifier={2}", code, WebUtility.UrlEncode(GlobalSetting.Instance.IdentityCallback), _codeVerifier);
var token = await _requestProvider.PostAsync<UserToken> (GlobalSetting.Instance.TokenEndpoint, data, GlobalSetting.Instance.ClientId, GlobalSetting.Instance.ClientSecret);
return token;
}
And then when I make a call…
RestClient rest = new RestClient(GlobalSetting.DefaultBaseUrl);
var request = new RestRequest("Partner/GetMyItem", Method.POST);
request.AddParameter("detail", MyEnumValue.ToString());
//tried both of the following…
request.AddParameter("Authorization", string.Format("Bearer {0}", Authorization.AccessToken), ParameterType.HttpHeader);
rest.AddDefaultHeader("Authorization", string.Format("Bearer {0}", Authorization.AccessToken));
IRestResponse res = rest.Post(request);
Function…
[HttpPost]
[ValidateInput(false)]
[AuthAttribute(Roles = …)]
[HandleForbidden]
public string GetMyItem(MyEnum detail)
In the server identity log I have the following…
2018-07-23 14:03:11.508 +00:00 [Information] Start authorize request
2018-07-23 14:03:11.508 +00:00 [Information] Start authorize request protocol validation
2018-07-23 14:03:11.508 +00:00 [Information] "Authorize request validation success"
"{
\"ClientId\": \"myMobile\",
\"ClientName\": \"myMobile App\",
\"RedirectUri\": \"https://localhost:44000/\",
\"AllowedRedirectUris\": [
\"https://localhost:44000/\",
...
],
\"SubjectId\": \"unknown\",
\"ResponseType\": \"code token\",
\"ResponseMode\": \"fragment\",
\"Flow\": \"Hybrid\",
\"RequestedScopes\": \"openid profile roles\",
\"State\": \"a971d692ae8f424493966023f5934b70\",
\"Nonce\": \"ec42d50463cc418dacbd04f1c43873d0\",
\"Raw\": {
\"client_id\": \"myMobile\",
\"client_secret\": \"myMobileSecret\",
\"response_type\": \"code token\",
\"scope\": \"openid profile roles\",
\"redirect_uri\": \"https://localhost:44000/\",
\"nonce\": \"ec42d50463cc418dacbd04f1c43873d0\",
\"state\": \"a971d692ae8f424493966023f5934b70\"
}
}"
2018-07-23 14:03:11.524 +00:00 [Information] User is not authenticated. Redirecting to login.
2018-07-23 14:03:11.524 +00:00 [Information] End authorize request
2018-07-23 14:03:11.524 +00:00 [Information] Redirecting to login page
2018-07-23 14:03:11.524 +00:00 [Debug] Protecting message: "{\"ReturnUrl\":\"https://....net/identity/connect/authorize?client_id=myMobile&client_secret=myMobileSecret&response_type=code%20token&scope=openid%20profile%20roles&redirect_uri=https%3A%2F%2Flocalhost%3A44000% 2F&nonce=ec42d50463cc418dacbd04f1c43873d0&state=a971d692ae8f424493966023f5934b70\",\"ClientId\":\"myMobile\",\"AcrValues\":[],\"Created\":636679513915083066}"
2018-07-23 14:03:11.570 +00:00 [Information] Login page requested
2018-07-23 14:03:11.570 +00:00 [Debug] signin message passed to login: "{
\"ReturnUrl\": \"https://...net/identity/connect/authorize?client_id=myMobile&client_secret=myMobileSecret&response_type=code%20token&scope=openid%20profile%20roles&redirect_uri=https%3A%2F%2Flocalhost%3A44000% 2F&nonce=ec42d50463cc418dacbd04f1c43873d0&state=a971d692ae8f424493966023f5934b70\",
\"ClientId\": \"myMobile\",
\"IdP\": null,
\"Tenant\": null,
\"LoginHint\": null,
\"DisplayMode\": null,
\"UiLocales\": null,
\"AcrValues\": [],
\"Created\": 636679513915083066
}"
2018-07-23 14:03:11.570 +00:00 [Information] rendering login page
2018-07-23 14:03:12.007 +00:00 [Information] CSP Report endpoint requested
2018-07-23 14:03:12.007 +00:00 [Information] CSP Report data: "{\"csp-report\":{\"document-uri\":\"https://...net/identity/login?signin=df9bdfc781a634b806ecc6555e9989ca\",\"referrer\":\"\",\"blocked-uri\":\"\",\"violated-directive\":\"script-src 'self'\",\"original-policy\":\"default-src 'self'; script-src 'self' ; style-src 'self' 'unsafe-inline' style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; img-src *; font-src font-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; report-uri https://devs3server.azurewebsites.net/identity/csp/report\",\"effective-directive\":\"script-src\",\"status-code\":200,\"source- file\":\"https://devs3server.azurewebsites.net/identity/login?signin=df9bdfc781a634b806ecc6555f9989ca\"}}"
2018-07-23 14:03:12.007 +00:00 [Information] Rendering 204
2018-07-23 14:03:26.772 +00:00 [Information] Login page submitted
2018-07-23 14:03:26.803 +00:00 [Information] Login credentials successfully validated by user service
2018-07-23 14:03:26.803 +00:00 [Information] Calling PostAuthenticateAsync on the user service
2018-07-23 14:03:26.819 +00:00 [Information] issuing primary signin cookie
2018-07-23 14:03:26.819 +00:00 [Information] redirecting to: https://....net/identity/connect/authorize?client_id=myMobile&client_secret=myMobileSecret&response_type=code token&scope=openid profile roles&redirect_uri=https:%2F%2Flocalhost:44000% 2F&nonce=ec42d50463cc418dacbd04f1c43873d0&state=a971d692ae8f424493966023f5934b70
2018-07-23 14:03:26.866 +00:00 [Information] Start authorize request
2018-07-23 14:03:26.881 +00:00 [Information] Start authorize request protocol validation
2018-07-23 14:03:26.881 +00:00 [Information] "Authorize request validation success"
"{
\"ClientId\": \"myMobile\",
\"ClientName\": \"my Mobile App\",
\"RedirectUri\": \"https://localhost:44000/\",
\"AllowedRedirectUris\": [
\"https://localhost:44000/\",
...
],
\"SubjectId\": \"2957b247-43ed-4aea-b5b4-c0a76a613942\",
\"ResponseType\": \"code token\",
\"ResponseMode\": \"fragment\",
\"Flow\": \"Hybrid\",
\"RequestedScopes\": \"openid profile roles\",
\"State\": \"a971d692ae8f424493966023f5934b70\",
\"Nonce\": \"ec42d50463cc418dacbd04f1c43873d0\",
\"SessionId\": \"3e67194d4c5ba7d1c8586948377f9fe7\",
\"Raw\": {
\"client_id\": \"myMobile\",
\"client_secret\": \"myMobileSecret\",
\"response_type\": \"code token\",
\"scope\": \"openid profile roles\",
\"redirect_uri\": \"https://localhost:44000/\",
\"nonce\": \"ec42d50463cc418dacbd04f1c43873d0\",
\"state\": \"a971d692ae8f424493966023f5934b70\"
}
}"
2018-07-23 14:03:26.881 +00:00 [Information] Creating Hybrid Flow response.
2018-07-23 14:03:26.881 +00:00 [Information] Creating Implicit Flow response.
2018-07-23 14:03:26.881 +00:00 [Debug] Creating access token
2018-07-23 14:03:26.881 +00:00 [Debug] Creating JWT access token
2018-07-23 14:03:26.912 +00:00 [Debug] Adding client "myMobile" to client list cookie for subject "2957b247-43ed-4aea-b5b4-c0a76a613942"
2018-07-23 14:03:26.912 +00:00 [Information] End authorize request
2018-07-23 14:03:26.912 +00:00 [Information] Redirecting to: https://localhost:44000/
2018-07-23 14:03:28.950 +00:00 [Information] Start token request
2018-07-23 14:03:28.950 +00:00 [Debug] Start client validation
2018-07-23 14:03:28.950 +00:00 [Debug] Start parsing Basic Authentication secret
2018-07-23 14:03:28.950 +00:00 [Debug] Parser found secret: "BasicAuthenticationSecretParser"
2018-07-23 14:03:28.950 +00:00 [Information] Secret id found: "myMobile"
2018-07-23 14:03:28.950 +00:00 [Debug] Secret validator success: "HashedSharedSecretValidator"
2018-07-23 14:03:28.950 +00:00 [Information] Client validation success
2018-07-23 14:03:28.950 +00:00 [Information] Start token request validation
2018-07-23 14:03:28.950 +00:00 [Information] Start validation of authorization code token request
2018-07-23 14:03:28.950 +00:00 [Information] Validation of authorization code token request success
2018-07-23 14:03:28.950 +00:00 [Information] Token request validation success
{
"ClientId": "myMobile",
"ClientName": "my Mobile App",
"GrantType": "authorization_code",
"AuthorizationCode": "dc7be1793efe246ca817d7d35298b355",
"Raw": {
"grant_type": "authorization_code",
"code": "dc7be1793efe246ca817d7d35298b355",
"redirect_uri": "https://localhost:44000/",
"code_verifier": ""
}
}
can someone please help me get a xamarin mobile app to work with identity server 3 to call apis?

Your API needs to be registered as a client with your Identity Server as a resource scope.
Then, you need to wire up bearer authentication in your API's middleware by using UseBearerTokenAuthentication. This is necessary so that the API can authorize incoming requests that are using the Authorization header with the Bearer Schema.
Finally, your mobile app needs to request that scope when issuing an authentication request. However, you also need to make sure your that Mobile app client is registered with that scope in Identity Server

Related

OnTeamsMessagingExtensionQueryAsync not getting hit

I am working on Microsoft.Bot.Builder for Teams for Search Message extension. My code is working fine in Local and Dev environment. But for production, I can see that OnTeamsMessagingExtensionQueryAsync not even get hit. I did remote debugging, it never reaches there and also I dont see any logs as well. I see that code reaches to the constructor(TeamsBot : TeamsActivityHandler) only. and then back to BotController api endpoint await _adapter.ProcessAsync(Request, Response, _bot);.
Can anyone help? I am clueless here. My Bot id and password is correct , the api endpoint is on Https. This was working yesterday and now it stopped. Below are the logs:
2022-12-21 08:09:06.421 +00:00 [Information] Microsoft.AspNetCore.Hosting.Diagnostics: Request starting HTTP/1.1 POST https://teams.Myonline.app/api/messages application/json;+charset=utf-8 1130
2022-12-21 08:09:06.421 +00:00 [Information] Microsoft.AspNetCore.Routing.EndpointMiddleware: Executing endpoint 'My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp)'
2022-12-21 08:09:06.421 +00:00 [Information] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Route matched with {action = "Post", controller = "Bot", page = ""}. Executing controller action with signature System.Threading.Tasks.Task PostAsync() on controller My.Office365.TeamsApp.Controllers.BotController (My.Office365.TeamsApp).
2022-12-21 08:09:06.422 +00:00 [Information] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Executing action method My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp) - Validation state: Valid
2022-12-21 08:09:06.422 +00:00 [Information] Microsoft.Bot.Builder.Integration.AspNet.Core.IBotFrameworkHttpAdapter: ProcessActivityAsync
2022-12-21 08:09:06.423 +00:00 [Information] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Executed action method My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp), returned result Microsoft.AspNetCore.Mvc.EmptyResult in 1.128ms.
2022-12-21 08:09:06.423 +00:00 [Information] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Executed action My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp) in 1.4924ms
2022-12-21 08:09:06.423 +00:00 [Information] Microsoft.AspNetCore.Routing.EndpointMiddleware: Executed endpoint 'My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp)'
2022-12-21 08:09:06.423 +00:00 [Information] Microsoft.AspNetCore.Hosting.Diagnostics: Request finished HTTP/1.1 POST https://teams.Myonline.app/api/messages application/json;+charset=utf-8 1130 - 401 - - 2.0425ms
2022-12-21 08:09:06.969 +00:00 [Information] Microsoft.AspNetCore.Hosting.Diagnostics: Request starting HTTP/1.1 GET https://teams.Myonline.app/ - -
2022-12-21 08:09:06.970 +00:00 [Information] Microsoft.AspNetCore.Routing.EndpointMiddleware: Executing endpoint '/_Host'
2022-12-21 08:09:06.970 +00:00 [Information] Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker: Route matched with {page = "/_Host", action = "", controller = ""}. Executing page /_Host
2022-12-21 08:09:06.970 +00:00 [Information] Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker: Executing an implicit handler method - ModelState is Valid
2022-12-21 08:09:06.970 +00:00 [Information] Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker: Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
2022-12-21 08:09:06.971 +00:00 [Information] Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker: Executed page /_Host in 1.0016ms
2022-12-21 08:09:06.971 +00:00 [Information] Microsoft.AspNetCore.Routing.EndpointMiddleware: Executed endpoint '/_Host'
2022-12-21 08:09:06.971 +00:00 [Information] Microsoft.AspNetCore.Hosting.Diagnostics: Request finished HTTP/1.1 GET https://teams.Myonline.app/ - - - 200 - text/html;+charset=utf-8 1.3705ms
2022-12-21 08:09:07.361 +00:00 [Information] Microsoft.AspNetCore.Hosting.Diagnostics: Request starting HTTP/1.1 POST https://teams.Myonline.app/api/messages application/json;+charset=utf-8 1128
2022-12-21 08:09:07.361 +00:00 [Information] Microsoft.AspNetCore.Routing.EndpointMiddleware: Executing endpoint 'My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp)'
2022-12-21 08:09:07.361 +00:00 [Information] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Route matched with {action = "Post", controller = "Bot", page = ""}. Executing controller action with signature System.Threading.Tasks.Task PostAsync() on controller My.Office365.TeamsApp.Controllers.BotController (My.Office365.TeamsApp).
2022-12-21 08:09:07.361 +00:00 [Information] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Executing action method My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp) - Validation state: Valid
2022-12-21 08:09:07.361 +00:00 [Information] Microsoft.Bot.Builder.Integration.AspNet.Core.IBotFrameworkHttpAdapter: ProcessActivityAsync
2022-12-21 08:09:07.362 +00:00 [Information] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Executed action method My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp), returned result Microsoft.AspNetCore.Mvc.EmptyResult in 1.2481ms.
2022-12-21 08:09:07.362 +00:00 [Information] Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Executed action My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp) in 1.4749ms
2022-12-21 08:09:07.362 +00:00 [Information] Microsoft.AspNetCore.Routing.EndpointMiddleware: Executed endpoint 'My.Office365.TeamsApp.Controllers.BotController.PostAsync (My.Office365.TeamsApp)'
2022-12-21 08:09:07.363 +00:00 [Information] Microsoft.AspNetCore.Hosting.Diagnostics: Request finished HTTP/1.1 POST https://teams.Myonline.app/api/messages application/json;+charset=utf-8 1128 - 401 - - 2.0420ms

Set-cookie ignored for HTTP response with status 302 in Spring Boot application

I implement certification through spring security.
If i receive targetUrl and authentication is successful, redirect to that targetUrl and create Cookie with that domain.
However, the Set-Cookie header does not work when testing in the local environment.
Request
Request URL: http://auth.develop.in/login?targetUrl=https://test2.test.develop.in/
Request Method: POST
Status Code: 302
Remote Address: 127.0.0.1:80
Referrer Policy: no-referrer-when-downgrade
Response
Response Header
Content-Length: 0
Date: Sat, 03 Aug 2019 16:38:06 GMT
Location: https://test2.test.develop.in/
Set-Cookie: JWT=eyJ0eXAiOiJKV1QiLpEls; Domain=test.develop.in; Path=/
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Code
fun setCookie(request: HttpServletRequest, response: HttpServletResponse, value: String) {
val cookie = Cookie(cookieName, value)
cookie.path = getCookiePath(request)
if (cookieDomain != null) {
cookie.domain = cookieDomain
}
response.addCookie(cookie)
}
Cookie {Cookie#9383}
name = "JWT"
value = "eyJ0eXAiOiJKV1Q~~"
version = 0
comment = null
domain = "test.develop.in"
maxAge = -1
path = "/"
secure = false
httpOnly = false
I expected Cookie to be created after being redirected normally.
Is there something I don't understand about Cookie?
If I don't redirect, cookies are created.
Problem solved.
Could not create cookies for test.develop.in on auth.develop.in
Change /etc/hosts domain auth.develop.in to auth.test.develop.in

Log Api Gateway request/response body/headers to ElasticSearch

It's easy to setup it by default, but i cannot change the format of messages. It sends to CloudWatch
Api Gateway works as proxy
2019-03-15 13:31:22.248 (REQ_ID) Method completed with status: 200
2019-03-15 13:31:22.248 (REQ_ID) Successfully completed execution
2019-03-15 13:31:22.248 (REQ_ID) Method response headers:
{Cache-Control=max-age=0, private, must-revalidate,
Content-Type=application/json; charset=utf-8, Date=Fri, 15 Mar 2019
13:31:22 GMT, ETag=W/"607046c7bacdeee5e27e99f48fa2e053",
Server=nginx/1.12.1 + Phusion Passenger 4.0.60, Status=200 OK,
Vary=Accept-Encoding, Origin, X-Content-Type-Options=nosniff,
X-Frame-Options=SAMEORIGIN, X-Powered-By=Phusion Passenger 4.0.60,
X-Request-Id=88c8f3c2-0a25-4445-9010-30d4753b855a, X-Runtime=0.030736,
X-XSS-Protection=1; mode=block, Connection=keep-alive}
2019-03-15 13:31:22.248 (REQ_ID) Method response body after
transformations: {"success":1,"message":"Token is invalid"}
2019-03-15 13:31:22.248 (REQ_ID) Endpoint response headers:
{Cache-Control=max-age=0, private, must-revalidate,
Content-Type=application/json; charset=utf-8, Date=Fri, 15 Mar 2019
13:31:22 GMT, ETag=W/"607046c7bacdeee5e27e99f48fa2e053",
Server=nginx/1.12.1 + Phusion Passenger 4.0.60, Status=200 OK,
Vary=Accept-Encoding, Origin, X-Content-Type-Options=nosniff,
X-Frame-Options=SAMEORIGIN, X-Powered-By=Phusion Passenger 4.0.60,
X-Request-Id=88c8f3c2-0a25-4445-9010-30d4753b855a, X-Runtime=0.030736,
X-XSS-Protection=1; mode=block, transfer-encoding=chunked,
Connection=keep-alive}
2019-03-15 13:31:22.248 (REQ_ID) Endpoint response body before
transformations: {"success":1,"message":"Token is invalid"}
2019-03-15 13:31:22.248 (REQ_ID) Received response. Integration
latency: 43 ms
2019-03-15 13:31:22.205 (REQ_ID) Sending request to
https://proxy.domain.com/api/endpoint
2019-03-15 13:31:22.205 (REQ_ID) Endpoint request body after
transformations: {"message":"hello world"}
2019-03-15 13:31:22.205 (REQ_ID) Endpoint request headers:
{x-amzn-apigateway-api-id=API, User-Agent=curl/7.54.0,
X-Forwarded-Proto=https, X-Forwarded-For=195.24.159.254,
content-type=application/json, X-Forwarded-Port=443,
X-Amzn-Trace-Id=Root=1-5c8ba92a-7fb7fa94b9991bb8f1561d55, accept=/}
2019-03-15 13:31:22.205 (REQ_ID) Endpoint request URI:
https://proxy.domain.com/api/endpoint
2019-03-15 13:31:22.119 (REQ_ID) Method request body before
transformations: {"message":"hello world"}
2019-03-15 13:31:22.119 (9f76246a-4726-11e9-a18d-25bda2ff1f7b) Method
request headers: {User-Agent=curl/7.54.0, X-Forwarded-Proto=https,
X-Forwarded-For=195.24.159.254, content-type=application/json,
Host=api.execute-api.eu-west-1.amazonaws.com, X-Forwarded-Port=443,
X-Amzn-Trace-Id=Root=1-5c8ba92a-7fb7fa94b9991bb8f1561d55, accept=/}
2019-03-15 13:31:22.119 (REQ_ID) Method request query string: {}
2019-03-15 13:31:22.119 (REQ_ID) Method request path:
{proxy=api/endpoint}
I need to send in JSON these 4 columns only: request_header, request_body, response_header, response_body to ES. Now it sends all the logs above for each request.

How do I solve getting 401 Unauthorized in response to attempting to obtain a token?

I've got an Identity Server (using IdentityServer4), a Web API that uses the Identity Server for authorization, and a Xamarin application that is using the Identity Server to log-in and authenticate the API.
When I run all three parts locally from Visual Studio I'm able to login using the Xamarin app, obtain a token, and use that token to make API calls. However, when I publish the Identity Server to a web server (on the same network), it fails at the point that it tries to get the token. So, it shows the login page, appears to accept the login, but the POST to get the token fails with the 401 Unauthorised error in the response.
I've also configured the Identity Server to allow Swagger to connect for testing the API, and that does allow me to sign in (using Implicit) using the Identity Server installed on a Web Server.
This is the method that does the POST in the Xamarin app (mostly copied from the eShopOnContainers example):
public async Task<TResult> PostAsync<TResult>(string uri, string data, string clientId, string clientSecret)
{
HttpClient httpClient = CreateHttpClient(string.Empty);
if (!string.IsNullOrWhiteSpace(clientId) && !string.IsNullOrWhiteSpace(clientSecret))
{
AddBasicAuthenticationHeader(httpClient, clientId, clientSecret);
}
var content = new StringContent(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();
TResult result = await Task.Run(() =>
JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));
return result;
}
Here's the calling method for getting the token:
public async Task<UserToken> GetTokenAsync(string code)
{
string data = string.Format("grant_type=authorization_code&code={0}&redirect_uri={1}&code_verifier={2}",
code, WebUtility.UrlEncode(Settings.Service.IdentityCallback), _codeVerifier);
var token = await _requestProvider.PostAsync<UserToken>(
Settings.Service.IdentityTokenEndpoint, data, Settings.Service.IdentityClientId, Settings.Service.IdentityClientSecret);
return token;
}
The uri is "http://myserver:5002/connect/token" and headers are:
Accept: "application/json"
Authorization: "Basic SW5zdGVtLkFDSVMuTW9iaWxlOnNlY3JldA=="
ContentType: "application/x-www-form-urlencoded"
The log on the web server gives me this:
info: IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator[0]
Showing login: User is not authenticated
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 3.4723ms 302
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3D0dc5d79410db46739c798ce004ac89b8%26code_challenge%3DAuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c%26code_challenge_method%3DS256%26state%3D031db7b77c7249aebb6f7ae205dac016
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Route matched with {action = "Login", controller = "Account"}. Executing action IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer)
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer) with arguments (/connect/authorize/callback?client_id=Company.App.Mobile&client_secret=secret&response_type=code%20id_token&scope=openid%20profile%20app_api%20offline_access&redirect_uri=http%3A%2F%2Fmyserver%3A5002%2FAccount%2FRedirect&nonce=0dc5d79410db46739c798ce004ac89b8&code_challenge=AuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c&code_challenge_method=S256&state=031db7b77c7249aebb6f7ae205dac016) - Validation state: Valid
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action method IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer), returned result Microsoft.AspNetCore.Mvc.ViewResult in 0.3611ms.
info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[1]
Executing ViewResult, running view Login.
info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[4]
Executed ViewResult - view Login executed in 1.7974ms.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer) in 2.4715ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 3.1044ms 200 text/html; charset=utf-8
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://myserver:5002/css/site.css
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
The file /css/site.css was not modified
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 0.6236ms 304 text/css
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://myserver:5002/lib/bootstrap/js/bootstrap.js
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
The file /lib/bootstrap/js/bootstrap.js was not modified
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 0.3461ms 304 application/javascript
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://myserver:5002/lib/jquery/jquery.js
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
The file /lib/jquery/jquery.js was not modified
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 0.2798ms 304 application/javascript
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://myserver:5002/icon.png
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
The file /icon.png was not modified
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 0.2655ms 304 image/png
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://myserver:5002/lib/bootstrap/css/bootstrap.css
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
The file /lib/bootstrap/css/bootstrap.css was not modified
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 0.26ms 304 text/css
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 POST http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3D0dc5d79410db46739c798ce004ac89b8%26code_challenge%3DAuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c%26code_challenge_method%3DS256%26state%3D031db7b77c7249aebb6f7ae205dac016 application/x-www-form-urlencoded 712
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Route matched with {action = "Login", controller = "Account"}. Executing action IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer)
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer) with arguments (IdentityServer4.Quickstart.UI.LoginInputModel, login) - Validation state: Valid
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
AuthenticationScheme: idsrv signed in.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action method IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer), returned result Microsoft.AspNetCore.Mvc.ViewResult in 1.0902ms.
info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[1]
Executing ViewResult, running view Redirect.
info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[4]
Executed ViewResult - view Redirect executed in 10.0474ms.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action IdentityServer4.Quickstart.UI.AccountController.Login (Company.IdentityServer) in 12.3805ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 13.1928ms 302 text/html; charset=utf-8
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://myserver:5002/connect/authorize/callback?client_id=Company.App.Mobile&client_secret=secret&response_type=code%20id_token&scope=openid%20profile%20app_api%20offline_access&redirect_uri=http%3A%2F%2Fmyserver%3A5002%2FAccount%2FRedirect&nonce=0dc5d79410db46739c798ce004ac89b8&code_challenge=AuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c&code_challenge_method=S256&state=031db7b77c7249aebb6f7ae205dac016
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint for /connect/authorize/callback
info: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint[0]
ValidatedAuthorizeRequest
{
"ClientId": "Company.App.Mobile",
"ClientName": "App Mobile",
"RedirectUri": "http://myserver:5002/Account/Redirect",
"AllowedRedirectUris": [
"http://myserver:5002/Account/Redirect"
],
"SubjectId": "eb194e4a-a2f7-482c-8c43-204567ebd591",
"ResponseType": "code id_token",
"ResponseMode": "fragment",
"GrantType": "hybrid",
"RequestedScopes": "openid profile app_api offline_access",
"State": "031db7b77c7249aebb6f7ae205dac016",
"Nonce": "0dc5d79410db46739c798ce004ac89b8",
"SessionId": "0ed1a950919c3b368e1249ec74e35f2c",
"Raw": {
"client_id": "Company.App.Mobile",
"client_secret": "secret",
"response_type": "code id_token",
"scope": "openid profile app_api offline_access",
"redirect_uri": "http://myserver:5002/Account/Redirect",
"nonce": "0dc5d79410db46739c798ce004ac89b8",
"code_challenge": "AuKmnO1hMcoEK3VeVNiVDka2U5F23HBnR0_MtxeWA3c",
"code_challenge_method": "S256",
"state": "031db7b77c7249aebb6f7ae205dac016"
}
}
info: IdentityServer4.Endpoints.AuthorizeCallbackEndpoint[0]
Authorize endpoint response
{
"SubjectId": "eb194e4a-a2f7-482c-8c43-204567ebd591",
"ClientId": "Company.App.Mobile",
"RedirectUri": "http://myserver:5002/Account/Redirect",
"State": "031db7b77c7249aebb6f7ae205dac016",
"Scope": "openid profile app_api offline_access"
}
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
AuthenticationScheme: idsrv signed in.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 40.3114ms 302
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://myserver:5002/Account/Redirect
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 0.9519ms 404
The address "http://myserver:5002/Account/Redirect" doesn't actually exist because the client is a Xamarin app, so I don't think the 404 at the end is an issue. There doesn't seem to be anything in the log for the call to obtain the token.
Here's the Client config for the Identity Server:
new Client
{
ClientName = "ACIS Mobile",
ClientId = "Instem.ACIS.Mobile",
AllowedGrantTypes = GrantTypes.Hybrid,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = {$"{identityUri}/Account/Redirect"},
RequireConsent = false,
RequirePkce = true,
PostLogoutRedirectUris = {$"{identityUri}/Account/Redirecting"},
AllowedCorsOrigins = { "http://xamarinapp" },
AllowedScopes = new List<string>
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess,
"acis_api"
},
AllowOfflineAccess = true,
AllowAccessTokensViaBrowser = true
},
new Client
{
ClientName = "Swagger UI",
ClientId="swaggerui",
AllowedGrantTypes=GrantTypes.Implicit,
AllowAccessTokensViaBrowser=true,
RedirectUris = { $"{webApiUri}/oauth2-redirect.html" },
PostLogoutRedirectUris={ $"{webApiUri}/" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"acis_api"
}
}
The Identity server startup configuration is pretty simple:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddIdentityServer()
.AddInMemoryClients(Config.GetClients(Configuration))
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddTestUsers(Config.GetUsers())
//.AddDeveloperSigningCredential();
.AddSigningCredential("some certificate thumbprint", System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, NameType.Thumbprint);
services.AddAuthentication()
.AddMicrosoftAccount(options =>
{
options.ClientId = "someclientid";
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientSecret = "somesecret";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseIdentityServer();
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
In IIS I've configured it to allow Anonymous and Basic authentication.
This is pretty much all new to me and I was making progress until this point, but I can't see any reason why it's giving me the 401 Unauthorized error, and I can't even see anything in any logs to give me anything to go on.
Edit:
I found a log file with more information:
2019-01-08 12:08:51 172.26.2.174 POST /Account/Login ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3Ddc06cb800d6f4f729df03a986ff2f165%26code_challenge%3DN343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo%26code_challenge_method%3DS256%26state%3D86f26cf6a5184d9a8263aac954711819 5002 - 172.16.190.147 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+WebView/3.0)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/64.0.3282.140+Safari/537.36+Edge/17.17134 http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3Ddc06cb800d6f4f729df03a986ff2f165%26code_challenge%3DN343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo%26code_challenge_method%3DS256%26state%3D86f26cf6a5184d9a8263aac954711819 302 0 0 156
2019-01-08 12:09:49 172.26.2.174 GET /connect/authorize/callback client_id=Company.App.Mobile&client_secret=secret&response_type=code%20id_token&scope=openid%20profile%20app_api%20offline_access&redirect_uri=http%3A%2F%2Fmyserver%3A5002%2FAccount%2FRedirect&nonce=dc06cb800d6f4f729df03a986ff2f165&code_challenge=N343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo&code_challenge_method=S256&state=86f26cf6a5184d9a8263aac954711819 5002 - 172.16.190.147 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+WebView/3.0)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/64.0.3282.140+Safari/537.36+Edge/17.17134 http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3Ddc06cb800d6f4f729df03a986ff2f165%26code_challenge%3DN343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo%26code_challenge_method%3DS256%26state%3D86f26cf6a5184d9a8263aac954711819 302 0 0 593
2019-01-08 12:10:33 172.26.2.174 POST /connect/token - 5002 Company.App.Mobile 172.16.190.147 - - 401 1 1326 50
2019-01-08 12:10:33 172.26.2.174 GET /Account/Redirect - 5002 - 172.16.190.147 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+WebView/3.0)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/64.0.3282.140+Safari/537.36+Edge/17.17134 http://myserver:5002/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3DCompany.App.Mobile%26client_secret%3Dsecret%26response_type%3Dcode%2520id_token%26scope%3Dopenid%2520profile%2520app_api%2520offline_access%26redirect_uri%3Dhttp%253A%252F%252Fmyserver%253A5002%252FAccount%252FRedirect%26nonce%3Ddc06cb800d6f4f729df03a986ff2f165%26code_challenge%3DN343zy63pcw_E75ET0HZQWGU_5ALC6H6sXt836z6mzo%26code_challenge_method%3DS256%26state%3D86f26cf6a5184d9a8263aac954711819 404 0 0 15
It's the connect/token line that has the 401 error.
I had Basic Authentication enabled in IIS for the Identity Server. Once I turned that off, it works fine.

rest assured sprint security login

I am trying to test my app using rest assured, I am using spring security
This is sthe code
RestAssured.baseURI = "http://myapp-breakid.rhcloud.com/";
RestAssured.port = 80;
Response response = expect().given().auth().form("admin", "sababa1.",springSecurity().withLoggingEnabled(new LogConfig())).
when().get("login");
but this is the response:
HTTP/1.1 302 Found
Date: Mon, 01 Dec 2014 20:38:57 GMT
Server: Apache-Coyote/1.1
Location: http://myapp-breakid.rhcloud.com/index
Content-Length: 0
Set-Cookie: JSESSIONID=32E5F577A6885826DF17ACEE4B3386AF; Path=/; HttpOnly
Accept-Ranges: none
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/plain
What am I missing ?
You don't need to go to the login page to login, REST Assured does this automatically. This works:
RestAssured.baseURI = "http://myapp-breakid.rhcloud.com";
RestAssured.authentication = form("admin", "sababa1.", springSecurity());
get("/index").prettyPrint();
What happens here is that form authentication is automatically performed before each request. If it's important to use the same session in multiple requests you should use a session filter. For example:
RestAssured.baseURI = "http://myapp-breakid.rhcloud.com";
SessionFilter sessionFilter = new SessionFilter();
given().
auth().form("admin", "sababa1.", springSecurity()).
filter(sessionFilter).
when().
get("/index");
// Session filter will automatically capture the session id and you can reuse it in subsequent requests.
given().
filter(sessionFilter).
when().
get("/another_protected_resource").
then().
statusCode(200);
You can also get the sessionId from the SessionFilter and use it like this:
given().
sessionId(sessionFilter.getSessionId()).
when().
get("/another_protected_resource").
then().
statusCode(200);

Resources