WCF Web API–building an Authorize attribute

This is the thirteenth post on a series about the WCF Web API Preview 4 and 5.  Last post focused on custom operation parameter conversion. This post shows how to also use operation handlers to build something similar to ASP.NET MVC’s AuthorizeAttribute.

The goal is to have an attribute to annotate operations with authorization requirements, such as the illustrated by the following excerpt.

[ServiceContract]
class TheService
{
    [Authorize("Alice")]
    [WebGet(UriTemplate="")]
    HttpResponseMessage Get(...)
    {
		...
    }
}

Notice the [Authorize(“Alice”)] requiring the request’s user to have the “Alice” identity name.

WCF Web API doesn’t have MVC’s filters. However, it is possible to have a similar behavior using operation handlers. The following figure shows the overall idea.

Authorize

 

  • The EnableAuthorizeAttribute configuration extension method checks if the operation’s description contains any AuthorizeAttribute. If so, it adds a AuthorizeOperationHandler instance to the operation handler pipeline. This instance receives the user identity extracted from the AuthorizeAttribute.
  • The AuthorizeOperationHandler declares one input parameter, of type IPrincipal. During the request processing, this handler checks if the input principal has the same identity as the one extracted from the AuthorizeAttribute. If not, it terminates the request before it reaches the operation, by throwing an HttpResponseException.
  • Notice that the AuthorizeOperationHandler is completely decoupled from the authentication process. The authorization’s only dependency is on a principal injected as a parameter.
  • If the operation doesn’t have a AuthorizeAttribute, then no AuthorizationOperationHandler is added to its pipeline.
  • Notice that the end developer only has to annotate the operations with the AuthorizeAttribute and call the EnableAuthorizeAttribute over the configuration, to enable this behavior.

Finally, the (draft) code is available at https://github.com/pmhsfelix/WcfWebApi.Preview5.Explorations.

10 thoughts on “WCF Web API–building an Authorize attribute

  1. Pingback: DelegatingHandler vs HttpOperationHandler – WCF Web API - Windows Azure Blog

  2. dk

    The problem I’m having with this approach is that it doesn’t work if your ServiceContract is defined on an interface but the Authorize attribute is on the concrete service implementation. Have you run into this? Any ideas on how I can inspect the combined set of attributes from the contract interface and the service implementation when configuring RequestHandlers?

    Reply
    1. pedrofelix Post author

      1) May I ask why are you separating the “contract interface” and the “service implementation”? This separation makes sense in the SOAP/WSDL model but not in a Web model.

      2) It should be possible to inspect the implementation’s method attributes. The root of the service description has a reference to the service implementation type.

      Reply
      1. dk

        Having the contract interfaces broken out was probably done out of old habits at first. However, I feel we’ve been able to derive a lot of value from this design even within a web model, particularly with things like testing. I can understand why it may not be necessary in a purely web model but I don’t see how having service contracts defined as an interface could be seen as a bad thing. I’m curious to hear your thoughts on why this wouldn’t make sense outside of a SOAP/WSDL model.

        BTW, I found a work around for HttpOperationDescription not having a reference to the implementation’s attributes… I made my authorization attribute implement IOperationBehavior (with no actual implementation code) and look for the behavior similar to the way that HttpServiceHost looks for WebGet attributes.

        i.e.
        var authorizationAttribute = operation.Behaviors.Find();

  3. Smitha

    Hi Pedro,
    Great articles. What is an email address I can reach you. I need some help on soap + ws security in wcf security. Reg encypting soap body. I have a sample vendor request

    Reply
      1. Smitha

        Hi Pedro, I am pasting this soap xml which needs to be generated.
        I have a usercertificate with privatekey, server cert with public key, username and password. I am able to generate all these tokens. Just need some clarifications on encryption. This would be a paid consultation

        MIICeDCC….(eMedNY signed user MLS cert)…….
        MIIDFj…..( eMedNY MLS web-service end-point public cert)……..

        ….your_username…..
        …..your_plaintext_password….
        KNyu6MsXCkTg4DDyvwvEiw==
        2010-09-15T18:00:30Z

        gpBAWt91pdwhKva…………

        SAMP L E R EQUE ST W I T H WS S E CURI T Y
        eMedNY Meds History Service User Guide Page 13 of 48 February 16, 2012
        Version 1.1

        wRUq………

        tBSsaZi……..

        SQsTCAK6ZaVhojB8+Y………

  4. Smitha

    Security

    MIICeDCC….(eMedNY signed user MLS cert)…….
    MIIDFj…..( eMedNY MLS web-service end-point public cert)……..

    ….your_username…..
    …..your_plaintext_password….
    KNyu6MsXCkTg4DDyvwvEiw==
    2010-09-15T18:00:30Z

    gpBAWt91pdwhKva…………

    SAMP L E R EQUE ST W I T H WS S E CURI T Y
    eMedNY Meds History Service User Guide Page 13 of 48 February 16, 2012
    Version 1.1

    wRUq………

    tBSsaZi……..

    <soapenv:Body wsu:Id="Id-f10674fd-b999-47c9-9568-c11fa5e5405b" xmlns:wsu="http://docs.oasis-

    Reply
  5. Pingback: Using owin’s interceptor for tokens presented to an odata webapi | Peter's ruminations

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s