ASP.NET WebAPI StatusCode: 401, ReasonPhrase: 'Unauthorized' - asp.net-web-api

The scenario I am talking is local debugging scenario as I have not deployed to azure yet.
I have a MVC Web App authenticating against AAD that calls WebAPI
I have the right permission set in the AAD tenant, the reason I say it set correctly because I am able to get the AccessToken for the WebAPI, but then when I try to call the WebAPI it gives me the following error
{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Pragma: no-cache
X-SourceFiles: =?UTF-8?B?xxxxxxxxxx
Cache-Control: no-cache
Date: Sun, 27 Mar 2016 02:06:31 GMT
Server: Microsoft-IIS/10.0
WWW-Authenticate: Bearer
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 61
Content-Type: application/json; charset=utf-8
Expires: -1
}}
Code
string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
NaiveSessionCache nsc = new NaiveSessionCache(userObjectID);
AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, nsc);
ClientCredential credential = new ClientCredential(clientId, appKey);
result = authContext.AcquireTokenSilent(todoListClientId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
Uri webApiUri = new Uri(string.Format("{0}{1}", todoListBaseAddress, "/api/TodoList"));
string accessTknString = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(result.AccessToken));
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, webApiUri);
request.Headers.Add(System.Net.HttpRequestHeader.Authorization.ToString(), string.Format("Bearer {0}", accessTknString));
HttpResponseMessage response = await client.SendAsync(request);

Related

Not able to consume WEB API hosted in same server

Below web API returns JSON for the given ID.
http://aws-av-devser/Assigning_ID/api/QidMasters/2
It's working as expected in postman.
but when I try to consume this web API in different projects on the same server. I am getting
404 Not found Error
Below is the code to consume the web API
var uri = "http://aws-av-devser/Assigning_ID/api/QidMasters/2";
var response = await httpClient.GetAsync(uri);
Error Message :
{
StatusCode: 404,
ReasonPhrase: 'Not Found',
Version: 1.1,
Content: System.Net.Http.HttpConnectionResponseContent,
Headers:
{
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 17 Jun 2022 17:59:28 GMT
Connection: close
Content-Type: text/html; charset=us-ascii
Content-Length: 315
}
}
Please correct me if I am missing something

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

Ambari api POST complaining CSRF protection

I am trying to set hbase property through Ambari API using following command
curl -u "admin:admin" -i -X POST -d '{"type": "hbase-site", "tag": "version3", "properties" : {"hbase.regionserver.global.memstore.size" : "0.6"}}' https://abct.net/api/v1/clusters/xyz/configurations
But keep getting following error
HTTP/1.1 400 Bad Request
Content-Length: 107
Content-Type: text/plain
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Microsoft-IIS/8.5
x-ms-hdi-active: 10.8.18.29
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
User: admin
X-Powered-By: ARR/3.0
Set-Cookie: AMBARISESSIONID=2e8ortl32j1p7zdjatigdgvg;Path=/;HttpOnly; path=/; secure
X-Powered-By: ASP.NET
Date: Mon, 12 Sep 2016 18:19:38 GMT
{
"status" : 400,
"message" : "CSRF protection is turned on. X-Requested-By HTTP header is required."
}
What am missing here ?
Turns out you have to add the request header to the request for anything other than a GET request.
You can add the header with
curl --header "X-Requested-By: my_computer_name"
Or
You can disable this feature.
I had same problem in c# Rest client. Using Brig's answer fixed it:
HttpClientHandler handler = new HttpClientHandler
{
Credentials = new System.Net.NetworkCredential("xxxx", "yyyyy"),
};
using (var httpClient = new HttpClient(handler))
{
//"X-Requested-By: my_computer_name"
httpClient.DefaultRequestHeaders.Add("X-Requested-By","my_computer_name");

Unable to POST data using TLS 1.2

I am trying to POST data to a server who is just using TLS1.2
When i am running the code i am getting the following response from server.
HttpResponseProxy{HTTP/1.1 415 Unsupported Media Type [Date: Wed, 07 Sep 2016 17:42:57 CST, Server: , Strict-Transport-Security: max-age=63072000; includeSubdomains; preload, Pragma: no-cache, Content-Length: 0, charset: ISO-8859-1, X-ORACLE-DMS-RID: 0, X-ORACLE-DMS-ECID: 343fa6c0-ed24-4003-ad58-342caf000404-00000383, Set-Cookie: JSESSIONID=1ZMIvt1NqrtWpHgHs4mMmYyTPUGTOQgrA9biCE3Dok5v0gDCPXu6!681252631; path=/; secure; HttpOnly;HttpOnly;Secure, Cache-Control: no-store, P3P: policyref="/w3c/p3p.xml", CP="WBP DSP NOR AMT ADM DOT URT POT NOT", Keep-Alive: timeout=5, max=250, Connection: Keep-Alive, Content-Type: text/xml, Content-Language: en] [Content-Type: text/xml,Content-Length: 0,Chunked: false]}
I am using the below code to post the data to server . I am using apache httpcomponents-client-4.5.2.
private static Registry<ConnectionSocketFactory> getRegistry() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext sslContext = SSLContexts.custom().build();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
new String[]{"TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
return RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionSocketFactory)
.register("https", sslConnectionSocketFactory)
.build();
}
public static void main(String[] args) throws Exception
{
PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(getRegistry());
clientConnectionManager.setMaxTotal(100);
clientConnectionManager.setDefaultMaxPerRoute(20);
HttpClient client = HttpClients.custom().setConnectionManager(clientConnectionManager).build();
HttpPost request = new HttpPost("https://someserver.com/dataupload");
File file = new File("C://Nible//code//_client//Request.xml");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setContentType(ContentType.TEXT_XML);
FileBody fileBody = new FileBody(file);
builder.addPart("my_file", fileBody);
HttpEntity reqEntity = builder.build();
request.setEntity(reqEntity);
HttpResponse response = client.execute(request);
System.out.println(response);
}
Can you please tell me what wrong am i doing?
I tried using below code instead of MultipartEntityBuilder. I am still getting the same error.
EntityBuilder builder = EntityBuilder.create();
builder.setFile(file);
builder.setContentType(ContentType.TEXT_XML);
If i am sending the BLANK REQUEST to server then also i am getting the same error. Blank error means i am not putting any thing in request just
HttpPost request = new HttpPost("https://someserver.com/dataupload");
HttpResponse response = client.execute(request);
I suspect of these lines in your code:
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setContentType(ContentType.TEXT_XML);
Multipart entities cannot be of content-type xml. They must be one of these types:
multipart/mixed
multipart/alternative
multipart/digest
multipart/parallel
(See RFC 1341 7.2)
I guess you should use one of these content-types for the multipart entity, and set text/xml as the content type of the single part:
FileBody fileBody = new FileBody(file, ContentType.TEXT_XML);
(Another issue is that I don't see necessary to send a multipart for just one file: You could leave out the MultipartEntityBuilder object and build directly a FileEntity.)

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