OAuth2 Web API 2 authentication - oauth-2.0

I'm learning how to secure a test API that I'm building and I want to implement security where a user signs up and then he requests an API Key which he will use in his app to authenticate to my API.
I started to implement this: https://github.com/vchatterji/OAuth2ClientCredentialGrant and I got the first part working where a user can signup and then request and receive a ConsumerKey & ConsumerSecret which is saved in an Azure table.
My problem is that I'm not sure what Flow I'm using The documentation doesn't state to change anything in StartupAuth:
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
I'm trying to authenticate with Fiddler and have tried many different requests but my most common error is unsupported grant type.
Based on what I have here what kind of grant type should I use?
Above it says to authenticate at /Token but other docs say api/token, which is the correct one?
Any help with composing the auth request would be greatly appreciated.

I was having the same issue for not having the data sent in the body of the request... Like this:
POST http://localhost:60543/oauth/token HTTP/1.1
Host: localhost:60543
Connection: keep-alive
Content-Length: 54
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36
Postman-Token: 85363928-a3d6-f9ad-c368-ab6019027a02
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en,fr;q=0.8,pt-PT;q=0.6,pt;q=0.4,en-US;q=0.2,es;q=0.2
username=peter&password=123456&grant_type=password
Make sure to set the content type in the header of the request.

Related

Is it possible to use Microsoft Clarity in Electron App? Getting 400 Bad request

I am trying to use Microsft-Clarity https://clarity.microsoft.com/ in my Electron App. I have added their integration steps in Head section of my app's main page. On running the app, in network section it is shoiwng network call to https://d/clarity.ms/collect but it is giving 400 bad request error in the response.
I am using Electron version 13.x
Is it possible to use Clarity in Electron app or not? Or do I need to make any specific changes to support it?
I have added the following code in head section of page
<script type="text/javascript">
(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "<Project_id>");
</script>
POST request is being made for the following URL:
https://d/clarity.ms/collect
Request header has following value
authority: d.clarity.ms
method: POST
path: /collect
scheme: https
accept: application/x-clarity-gzip
accept-encoding: gzip, deflate, br
accept-language: en-US
content-length: 285595
cookie: MUID=XXXXXXXXXXXXXXXXXXXXX
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) XXXXXX/XXXXX Chrome/91.0.4472.164 Electron/13.6.9 Safari/537.36
Getting the following response for the request
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title":"Bad Request",
"status":400,
"traceId":"00-xxxxxxxxxxxxxxx-xxxxxxxxxxxx-00"
}

Initiate SingleSignOn by Saml2PostBinding

I am having an issue when using ITfoxtec for ASP.NET Core 3.0.
As context I am trying to establish a connection between a webapplication and a third-party login service. To encapsulate some of the possibilities beforehand, the third-party has access to our metadata-url and configured their services for our webapplication.
Desired user workflow:
User enters the webapplication;
User clicks a button which redirects the user to the login service;
User logs in on the service and redirects back to the given returnURL;
Afterwards the webapplication determines permission based on the provided sso-cookie.
Steps taken so far:
Added Saml2 section in appsettings.json containing our metadata.xml and issuer. The issuer name equals the given EntityID provided within the metadata.xml. It is made anonymous in the given context, like so:
"Saml2": {
"IdPMetadata": "wwwroot/SAML/Metadata.xml",
"Issuer": "myIssuerName",
"SignatureAlgorithm": "http://www.w3.org/2000/09/xmldsig#rsa-sha1",
"CertificateValidationMode": "ChainTrust",
"RevocationMode": "NoCheck",
"SigningCertificateFile": "\\licenses\\certificate.pfx",
"SigningCertificatePassword": "password1"
},
Added Saml2Configuration in startup.cs;
services
.Configure<Saml2Configuration>(Configuration.GetSection("Saml2"))
.Configure<Saml2Configuration>(configuration =>
{
configuration.SigningCertificate = CertificateUtil.Load(
$"{Environment.WebRootPath}{Configuration["Saml2:SigningCertificateFile"]}",
Configuration["Saml2:SigningCertificatePassword"]);
configuration.AllowedAudienceUris.Add(configuration.Issuer);
var entityDescriptor = new EntityDescriptor();
entityDescriptor.ReadIdPSsoDescriptorFromFile(Configuration["Saml2:IdpMetadata"]);
if (entityDescriptor.IdPSsoDescriptor == null) throw new Exception("Failed to read the metadata.");
configuration.SignAuthnRequest = true;
configuration.SingleSignOnDestination = entityDescriptor.IdPSsoDescriptor.SingleSignOnServices
.Where(ed => ed.Binding.ToString() == "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")
.First().Location;
configuration.SignatureValidationCertificates.AddRange(entityDescriptor.IdPSsoDescriptor.SigningCertificates);
});
Here comes the tricky part; By default the sso initiation does a request with a RedirectBinding which does therefore send a GET request towards the sso service. However, the service I am trying to approach expects a SAMLRequest as a POST request. So I have changed the code by initiating with PostBinding request and afterwards directly submit the form, like so:
public IActionResult Initiate([FromQuery(Name = "returnUrl")] string returnUrl = "")
{
var binding = new Saml2PostBinding();
binding.SetRelayStateQuery(new Dictionary<string, string> { { "ReturnUrl", returnUrl } });
binding.Bind(new Saml2AuthnRequest(_saml2configuration)
{
ForceAuthn = false,
IsPassive = false,
NameIdPolicy = new NameIdPolicy() { AllowCreate = true },
AssertionConsumerServiceUrl = new Uri("https://localhost:44366/api/Authentication/Process"),
});
return binding.ToActionResult();
}
Issue:
However, after sending the base64 encoded AuthnRequest as SAML Request, I am receiving a 403 Forbidden from the third-party login. At this stage I am not certain whether is the identity provider not being configured properly or my request lacking something. What am I doing wrong?
Below is the (anonymously made) request headers.
Assume that the SAMLRequest is provided in formdata as base64 encoded.
:authority: myEntityDescriptorName
:method: POST
:path: mySsoURL
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
accept-encoding: gzip, deflate, br
accept-language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7
cache-control: no-cache
content-length: 3582
content-type: application/x-www-form-urlencoded
cookie: JSESSIONID=3D5FE88D55674C2F1E3646E6D8A0FFBE
origin: https://localhost:44366
pragma: no-cache
referer: https://localhost:44366/
sec-fetch-mode: navigate
sec-fetch-site: cross-site
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36
It is correct to change the Authn Request to a Post binding if that is required.
Your application is a Service Provider (also called Relying Party) which needs to be configured at the Identity Provider with a unique Issuer name.
I think the problem is that the Issuer name you have configured ("Issuer": "myIssuerName") is incorrect. The issuer name should be your Service Providers issuer name, not the Identity Provider Issuer name from the metadata.xml.

Fetch with ReadableStream as Request Body

I'm trying to use fetch with a ReadableStream. In this example, the ReadableStream should simply repeat "Some data..." indefinitely.
fetch('/', {
method: 'POST',
body: new ReadableStream({
pull: function(controller) {
console.log('pull called!');
controller.enqueue('Some data...');
}
})
});
This doesn't work. While pull is executed once, no data is sent in the request body.
POST / HTTP/1.1
Host: example.com
Connection: keep-alive
Content-Length: 0
Origin: https://example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
Accept: */*
Referer: https://example.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
How can I make a ReadableStream (or any kind of stream where I can write dynamic data) usable with fetch?
Alternatively, if this isn't yet possible, could you please indicate this? Thank you.
Note: This is a more specific spin-off question from: Method for streaming data from browser to server via HTTP
We're working on making this work, see https://github.com/whatwg/fetch/pull/425 for the PR to the Fetch Standard. Once that is done you can expect this to make its way into browsers (slowly).

Principal is null when CSRF disabled

I'm creating a webapp that uses spring-boot-starter-security and spring-security-oauth2 to use Facebook for login.
To avoid implementing all that CSRF-stuff in angular 2 (and because it's just a toy project) I want to turn off CSRF.
I have implemented the following configuration:
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
But now the Principal-Object is always null:
Task createTask(#RequestBody Task task, Principal principal) {
// do stuff
}
Why?
I guess I unintentionally overwrite the security config configured in my application.yaml, but even if I add an Order-Annotation it doesn't work :(
Edit:
Request headers (I created a Filter to add a XSRF-TOKEN cookie, ignore that):
POST /foo HTTP/1.1
Host: localhost:81
Connection: keep-alive
Content-Length: 15
Origin: http://localhost:81
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36
Content-Type: application/json
Accept: */*
Referer: http://localhost:81/create-task
Accept-Encoding: gzip, deflate
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: _ga=GA1.1.681162454.1458756836; JSESSIONID=F65FB28C14A8A2D870D18842DE855212; XSRF-TOKEN=551858ab-678e-4dcb-bc72-44fbc569ec41

DART HttpRequest does not provide authorization header for CORS OPTIONS request

I try to do a POST request with HttpRequest (dart:html) to call a rest service secured with basic authentication.
HttpRequest request = new HttpRequest(); // create a new XHR
var url = "http://localhost:8082/xyz";
request.open("POST", url, async: false); // POST the data to the server
String username = "foo";
String password = "bar";
final auth = CryptoUtils.bytesToBase64(UTF8.encode("$username:$password"));
request.setRequestHeader('authorization',"Basic $auth");
request.setRequestHeader('content-type',"application/json");
request.setRequestHeader("accept", "application/json");
String jsonData = '{"language":"dart"}'; // etc...
request.send(jsonData); //exception 401 Unauthorized
Before performing the POST call the OPTIONS call is performed (issued by dart:html) without the authorization header. This leads into an 401 Unauthorized response.
Request header:
Accept:*/*
Accept-Encoding:
gzip,deflate,sdch
Accept-Language:
en-US,en;q=0.8
Access-Control-Request-Headers:
authorization, content-type, accept
Access-Control-Request-Method:
POST
Cache-Control:
max-age=0
Connection:
keep-alive
Host:
localhost:8082
Origin:
http://localhost:63342
Referer:
http://localhost:63342/dart_client/test/all_test.html
User-Agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.0 (Dart) Safari/537.36
Reponse header:
Content-Length:
0
Date:
Mon, 02 Feb 2015 23:33:58 GMT
Server:
Jetty(9.2.7.v20150116)
WWW-Authenticate:
basic realm="xyzrealm"
Is there a way to provide the authorization header to the OPTIONS call?
Any suggestions would be great. Thanks
The OPTIONS request is made by the browser automatically and you can't modify that request. The server needs to allow the OPTIONS preflight request without authentication.
See http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
The user credentials are excluded.

Resources