GithubHelp home page GithubHelp logo

hawknet's Introduction

hawknet

Hawk protocol implementation for .NET. Hawk is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial HTTP request cryptographic verification.

The project includes a basic library for generating/verifying a Hawk authorization header, and set of integration projects for existing web frameworks such as ASP.NET Web API or ServiceStack. An OWIN handler is also included, which can used for any OWIN compatible implementation.

hawknet's People

Contributors

born-in-brooklyn avatar brannonking avatar odelljl avatar tugberkugurlu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hawknet's Issues

timestampskew issue

Please check the Timestamp validation in the Checkstamp check

in the GetAuthorizationHeader why divide by 1000, since the value is supposed to be seconds?

    var normalizedTs = (ConvertToUnixTimestamp((ts.HasValue)
            ? ts.Value : DateTime.UtcNow)).ToString(); //removed / 1000

this causes issues in the CheckTimeStamp

    private static bool CheckTimestamp(string ts, int timestampSkewSec)
    {
        double parsedTs;
        if (double.TryParse(ts, out parsedTs))
        {
            var now = ConvertToUnixTimestamp(DateTime.Now);

            // Check timestamp staleness
            if (Math.Abs(parsedTs - now) > timestampSkewSec) //* 1000 
            {
                return false;
            }
            else
            {

AllowAnonymous doesn't work

Hi,
I just downloaded and tested the project, since I need something similar, and I found that the AllowAnonymous attribute it is not working at all.

In your test that seems to work because you are already using and authorized client.
If you modify your test code (lines 64 to 69 in Example.cs) to the following, you will see the issue:

var client2 = new HttpClient();
var request2 = new HttpRequestMessage(HttpMethod.Get, "http://localhost:8091/Api/HelloWorldAnonymous");
request2.Headers.Host = "localhost";

var response2 = client2.SendAsync(request2).Result;
var message2 = response2.Content.ReadAsStringAsync().Result;
Console.WriteLine("Response {0} - Http Status Code {1}", message2, response2.StatusCode);

Use ClaimsPrincipal/ClaimsIdentity

Hey,

it would be better to use ClaimsPrincipal instead of HawkPrincipal. Turn the outcome of the authentication into some claims and add them to claims collection.

That would play much nicer with the rest of .net/wif.

cheers
dominick

Owin hosting non standard port and bad mac

I know you already noticed this yourself. When you use owin hosting the authentication fails because the port is not set correctly you can see this when the normalized string is printed in the trace.

Is there any update or workaround? maybe force a configurable value?

httprequest depreciation - Later ASP.Net Core versions and httpclient

We currently use hawknet on asp.net 4.8 and am switching to .Net Core 6 and Blazor and as part of this the httprequest has been depreciated so we have switched to httpclient instead but I am struggling to get the code to work and the issue seems to be down to the hawk signing.
I don't suppose you have any sample code for httpclient do you as it would be a great help and worth having the updated example.

Thank you
Simon

Problems validating bewit when url contains spaces encoded as %20

Hi Pablo.
When using urls that have spaces encoded as %20 instead of a plus sign (both are valid, apparently), the code is failing. This is because of a behavior in the object return from HttpUtility.ParseQueryString(uri.Query) in the method RemoveBewitFromQuery.
This object, when ToString() is invoked, replaces %20 with the "+" sign. As a consequence, the resulting url doesn't match the original used to generate the mac, and the check fails.

A failing test:

       [TestMethod]
        public void ShouldAuthenticateBewitWithEncodedUrlWithPercentSpaces()
        {
            var credential = new HawkCredential
            {
                Id = "1",
                Algorithm = "sha1",
                Key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn",
            };

            var bewit = Hawk.GetBewit("example.com", new Uri("http://example.com:8080/resource/4?path=%2Fmovie%2Fcomedy%20club%2F2014"), credential,
                200, "hello");

            var claims = Hawk.AuthenticateBewit(bewit, "example.com", new Uri("http://example.com:8080/resource/4?path=%2Fmovie%2Fcomedy%20club%2F2014&bewit=" + bewit),
                s => credential);

            Assert.IsNotNull(claims);
        }

Time units mismatch

The ShouldFailWithTimestampInThePast test fails if a timestamp 100 seconds behind is used. The tests are using 1 day which contains more than 1000 seconds, and that's way they succeed.

The ConvertToUnixTimestamp method returns the number of seconds since the epoc. However, the GetBewit method (and probably others) then use var expiration = Math.Floor(now / 1000) + ttlSec;. The value of now is already in seconds.

Since the timestamp in the bewit is in seconds, I'd suggest always using seconds as the time unit. This would also remove all the /1000 and *1000 code.

Query string encoding bug

I believe there is an issue with the RemoveBewitFromQuery method.

Using the example URL below which contains encoded characters in the query string:

http://www.example.org/test?path=%2Fmovie%2Fcomedy%2F2014

The Hawk.GetBewit method will compute the MAC using the encoded path and query string above. No issues there.

However the Hawk.AuthenticateBewit method when calculating the MAC removes the bewit. In doing so it recreates the query string which removes the encoding so the MAC ends up using an un-encoded path and query string i.e.

test?path=/movie/comedy/2014

This results in a different MAC and therefore a "Bad mac" SecurityException is thrown.

The issue relates to the code below:
Hawk.cs > RemoveBewitFromQuery()
var resultingQuery = string.Join("&", parsedQueryString.Cast().Select(e => e + "=" + parsedQueryString[e]).ToArray());

Changing this to:
var resultingQuery = parsedQueryString.ToString();

Resolves the issue.

Exception: The format of value '<null>' is invalid

When running Example.Owin against a non-secured controller (no Authorize attribute) and no signed http client, the exception The format of value '< null >' is invalid is thrown. This is happening in the file hawknet.owin\hawkauthenticationhandler.cs, line 156 due to an unsafe attempt to parse Request.Headers["authorization"]:

https://github.com/pcibraro/hawknet/blob/master/HawkNet.Owin/HawkAuthenticationHandler.cs#L156

var authorization = AuthenticationHeaderValue.Parse(Request.Headers["authorization"]);

I fixed it by modifying line 154 to:
https://github.com/pcibraro/hawknet/blob/master/HawkNet.Owin/HawkAuthenticationHandler.cs#L154

if (this.Options.IncludeServerAuthorization && Request.Headers.ContainsKey("authorization"))

Not sure if this breaks your security logic, if it doesn't do you think this fix could be included in the Nuget package?

Thanks

Camilo

normalized string formatting in CalculateMac()

re: CalculateMac() method
please look at the normalized string. i believe this is a more consistent formatting of it

//old lines in question
//((!string.IsNullOrEmpty(ext)) ? ext : "") + "\n";
// compared to java - escaped newline
//((!string.IsNullOrEmpty(payloadHash)) ? payloadHash + "\n" : "") +
//compared to java version - add \n always after

//proposed string for normalized var

        var normalized = "hawk.1." + type + "\n" +
                    ts + "\n" +
                    nonce + "\n" +
                    method.ToUpper() + "\n" +
                    uri.PathAndQuery + "\n" +
                    host.ToLower() + "\n" +
                    uri.Port.ToString() + "\n" +
                    ((!string.IsNullOrEmpty(payloadHash)) ? payloadHash : "") + "\n" +
                    ((!string.IsNullOrEmpty(ext)) ? ext.Replace("\\", "\\\\").Replace("\n", "\\n") : "") + "\n";

Not working with attribute routing

Hey,

Started using HawkNet on a new project where I can't use HTTPS, and it does the trick. However, I would like to use the Web API 2 "Attribute routing" feature in my project, but unfortunately it seems that this style of routing doesn't support the custom message handlers that are needed to implement HawkNet (ie the the handler that returns the HawkCredential). Is there any other way ? Or should I just stick with the classic routing system ?

Thanks

utf8 encoding vs ascii

compared to java implementation there are places where ascii encoding is being used for encoding message and key. The java implementation has 100% utf encoding for key and message text

var messageBytes = Encoding.UTF8.GetBytes(normalized);
vs
var messageBytes = Encoding.ASCII.GetBytes(normalized);

payload hash formatting missing

There is no formatting applied to the payload before hashing and thus can be missed by an implementer

string.Format("hawk.1.payload\n{0}\n{1}\n", headerContentType.ToLower(), payload);

uri.PathAndQuery.ToLower() is not working and return "Bad mac"

Hawk.cs:

the code in CalculateMac method, when i remove ToLower() ,and work well

var normalized = "hawk.1." + type + "\n" +
ts + "\n" +
nonce + "\n" +
method.ToUpper() + "\n" +
uri.PathAndQuery.ToLower() + "\n" +
sanitizedHost.ToLower() + "\n" +
uri.Port.ToString() + "\n" +
((!string.IsNullOrEmpty(payloadHash)) ? payloadHash : "") + "\n" +
((!string.IsNullOrEmpty(ext)) ? ext : "") + "\n";

Post Not Returning Response

I am having an issue where a post WebApi method is not returning a response to the consuming client.

The client is another controller in the same solution/website (for testing purposes)

When I remove the Authorize attribute from the Post method everything works as expected and I recieve the response from the post method.
Client Method calling the post method

        Dim postUri As String = "1/client/DataXChangeTester/type/CollisionReport"

        Dim leftChild As New QueryNode With {.NodeValue = "drivers.name.lastName"}
        Dim rightChild As New QueryNode With {.NodeValue = "McNear"}

        Dim simpleOperation As New QueryNode With {.NodeValue = "is",
                                                  .LeftNode = leftChild,
                                                   .RightNode = rightChild}

        Dim queryToSend As QueryDetails = New QueryDetails With {.QueryDetail = simpleOperation}

        TesterClient = New HttpClient(HawkClientHandler)
        'TesterClient = New HttpClient()
        Dim webAddress As String = ConfigurationManager.AppSettings("ServiceURL")
        TesterClient.BaseAddress = New Uri(webAddress)

        TesterClient.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))

        Dim action = TesterClient.PostAsync(postUri, queryToSend, New JsonMediaTypeFormatter())

        '30 second timeout.
        action.Wait(30000)


        Dim response As HttpResponseMessage = action.Result

        If response.IsSuccessStatusCode Then
            ViewData("PredefinedQueryMessage") = response.Content.ReadAsStringAsync().Result
            Return View("Index")
        Else
            ViewData("PreDefinedQueryErrorMessage") = response.Content.ReadAsStringAsync().Result
            Return View("Index")
        End If

Client credential and message handler setup

 TestCredential = New HawkCredential With {
            .Id = "BuyCrashTN",
            .Algorithm = "sha256",
            .Key = "1531d118-ae19-11e3-b324-28cfe9215d9f"}

        HawkClientHandler = New HawkClientMessageHandler(New HttpClientHandler(), TestCredential)

Server side code

WEBApiConfig

 Dim handler As New HawkMessageHandler(New HttpControllerDispatcher(config),
                                              Function(credential)
                                                  Return Task.FromResult(RetrieveCredential(credential))
                                              End Function)

Post Method

 'POST 'api/1/client/ClientName/type/TypeName
    <Authorize>
    <AcceptVerbs("POST")>
    Public Function Query(requestMessage As HttpRequestMessage,
                          clientId As String,
                          typeName As String,
                          <FromBody> requestedQuery As QueryDetails) As HttpResponseMessage
        Dim responseContents As New QueryResults()
        Dim response As HttpResponseMessage
        Dim requestId As Integer = -1
        Try
            requestId = LogRequest("Received Query", requestedQuery)
            ReportType = GetType(DataXChangeCollisionQuery)
            Parameter = Expression.Parameter(ReportType, "report")
            responseContents = ExecuteQuery(requestedQuery)
            response = requestMessage.CreateResponse(HttpStatusCode.OK, responseContents)
        Catch ex As Exception
            response = requestMessage.CreateErrorResponse(HttpStatusCode.InternalServerError, "Error Processing Provided Query")
        End Try
        LogRequest("Exiting Query Operation", requestedQuery, requestId)

        Return response
    End Function

standard mismatch: ext-parameter shall be placed before mac-parameter

According to the documentation the ext-parameter - if present - shall be placed before the mac parameter.

The hawk parameters shall be ordered in this sequence:

  1. id
  2. ts
  3. nonce
  4. hash
  5. ext
  6. mac

According to this sourcefile the order differs:

  1. id
  2. ts
  3. nonce
  4. mac
  5. ext
  6. hash

I found this issue when working with an hawk-protected api which didn't accept incorrect ordered parameters. It would be stunning if you could fix this issue.

I download the simple,and run Example project,First client request and response "Bad mac"

var clientHandler = new HawkClientMessageHandler(new HttpClientHandler(), credential, "some-app-data");
var client = new HttpClient(clientHandler);

            var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:8091/api/HelloWorld");
            request.Headers.Host = "localhost";

            var response = client.SendAsync(request).Result;
            string message = response.Content.ReadAsStringAsync().Result;
            Console.WriteLine("Response {0} - Http Status Code {1}", message, response.StatusCode);

Additional:
I change url to http://localhost:28290/api/HelloWorld and run Example.Web project,is work well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.