Passing display=touch to Facebook OAuth with Microsoft OWIN - asp.net-mvc

I have an ASP.NET MVC5 app which I have configured for Facebook OAuth 2 login using the ASP.NET OWIN authentication model that ships with this version of MVC.
I want to tell Facebook to optimize its login page for touch-based devices. Facebook documentation says I should be able to do this by adding a display=touch parameter to the query string we pass to Facebook when we kick off the OAuth flow. (see https://developers.facebook.com/docs/reference/dialogs/oauth/)
This ought to be a simple thing to do, but I am at a total loss about how to go about customizing the various OWIN middleware classes to add this parameter.
How do I customize the OWIN auth flow to modify the Facebook OAuth URL?

Basically: you need to go ahead and create an authentication provider for Facebook. So create a class that inherits from FacebookAuthenticationProvider. Within this class, override the "ApplyRedirect" method. Make it look something like:
public override void ApplyRedirect(FacebookApplyRedirectContext context)
{
context.Response.Redirect(context.RedirectUri + "&display=popup");
}
Now simply wire this class up with your configuration, like so:
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
Provider = new **<the name of the class that you created>**()
// the rest of your configuration such as app ID and secret
});
And that should be it!
Answer courtesy of #nlaq here: Facebook PopUp Login with Owin

Related

Pass field values from mvc application to the b2c sign up custom policy filelds

I have email field in my MVC application. Once user given email-Id we are validating and have to pass the same email-id to the Azure B2C SignUp policy. For this I have created custom policy. Can any body help me how I can achieve this.
See another answer at here for how this can be implemented using a custom policy.
It requires the email address to be passed as an input claim from the relying party application to the custom policy in a JWT that is signed with the client secret of the relying party application.
A working sample of this is here.
I was able to do this using a custom B2C policy.
I had a predefined extension attribute called registrationNumber that I wanted to pre-populate on my SignUp policy. Here is how to create a custom attribute.
I added registrationNumber as a ContentDefinitionParameter on the SignUp Policy.
<ContentDefinitionParameters>
<Parameter Name="registrationNumber">{OAUTH-KV:registrationNumber}</Parameter>
</ContentDefinitionParameters>
Still in the SignUp Policy, I added an output claim for the extension attribute.
<OutputClaim ClaimTypeReferenceId="extension_RegistrationNumber" AlwaysUseDefaultValue="true" DefaultValue="{OAUTH-KV:registrationNumber}"/>
Then, in my MVC app I add the parameter on redirect.
OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification notification)
notification.ProtocolMessage.Parameters.Add("registrationNumber", registrationNumber);
EDIT: As Chris Padgett points out, this is only applicable for pre-populating the sign-in email address, but the need was for sign-up. Chris's answer is better for sign-up.
If I understand correctly, your MVC application is the relying party that is redirecting to B2C for authentication and you want to prepoulate the email address box in B2C with the email address you collected in the MVC application.
The mechanism you are looking for is the OpenID Connect login_hint query string parameter in the authentication request that is sent to the B2C autorization endpoint.
B2C supports this parameter and provides instructions on how to read the login_hint with custom policy.
During a sign-in user journey, a relying party application may target
a specific user or domain name. When targeting a user, an application
can specify, in the authorization request, the login_hint query
parameter with the user sign-in name. Azure AD B2C automatically
populates the sign-in name, while the user only needs to provide the
password.
If you are using a custom policy, override the
SelfAsserted-LocalAccountSignin-Email technical profile. In the
section, set the DefaultValue of the signInName claim to
{OIDC:LoginHint}. The {OIDC:LoginHint} variable contains the value of
the login_hint parameter. Azure AD B2C reads the value of the
signInName claim and pre-populates the signInName textbox.
I don't know exactly how your application is built, but I'll assume that your MVC application is similar to the TaskWebApp described in Quickstart: Set up sign-in for an ASP.NET application using Azure Active Directory B2C. If this is the case you need to make two changes.
First, in your AccountController SignUpSignIn() method (or wherever it is you have the validated email address and are ready to redirect to B2C), you need to add the email address to the OWIN context.
public void SignUpSignIn()
{
if (!Request.IsAuthenticated)
{
var validatedEmailId = "emailaddress#example.com"; //read from form
HttpContext.GetOwinContext().Set("validatedEmail", validatedEmailId);
HttpContext.GetOwinContext().Authentication.Challenge();
return;
}
Response.Redirect("/");
}
Then in your Startup.Auth.cs, you need to modify the OnRedirectToIdentityProvider() callback to read the email address from the environment and use that as the LoginHint value.
private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
var policy = notification.OwinContext.Get<string>("Policy");
if (!string.IsNullOrEmpty(policy) && !policy.Equals(DefaultPolicy))
{
notification.ProtocolMessage.Scope = OpenIdConnectScopes.OpenId;
notification.ProtocolMessage.ResponseType = OpenIdConnectResponseTypes.IdToken;
notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(DefaultPolicy.ToLower(), policy.ToLower());
}
else //default, sign-in/sign-up
{
notification.ProtocolMessage.LoginHint =
notification.OwinContext.Get<string>("validatedEmail");
}
return Task.FromResult(0);
}

ASP.NET Core API Facebook registration/login

I'm working on ASP.NET Core API and need to add option to register with social service, e.g. Facebook.
Scenario should be e.g. Android App user should click "Sign up with Facebook" at startup, then Facebook app should open then user should click confirm and be registered in app.
Default Asp.net web example shows how to do it with web page on same host as APIs with return Challenge() response that basically returns HTML page as I understood.
What is the correct flow here and is there any existing libraries to do that?
As I understand now flow is something like this:
1. API server has my AppId and AppSecret from Facebook
2. Android app should request "applciation token" from API server
3. Android app should call Facebook with that token and get "user confirmation token"
4. Android app should pass "user confirmation token" to API server
5. API server should call Facebook with "AppId/AppSecret token + user confrimation token" and get details about user and create local user in database.
6. API server should create "API token" for that user
7. Android app should use "API token"
So at least I want to understand what to replace this code from example with:
public IActionResult ExternalLogin(string provider, string returnUrl = null) {
// Request a redirect to the external login provider.
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
var properties = signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
the thing to understand is the default web app template provided in VS 2015 uses ASP.NET Identity with cookie authentication. cookie auth works for web browsers but for an android app to authenticate you would need something to issue jwt tokens in addition to or instead of cookies. There is nothing built in provided by Microsoft for that in asp.net core, the recommendation is to use IdentityServer4

Double authentication with Web app & Web API needed?

I'm stuck on how to solve following problem.
I'll start with describing what my app looks like in a general context.
[ ASP MVC (Angular App) ]
Uses Owin cookie
[ WEB API 2 ]
Uses Oauth Token Bearer
This scenario is happening:
User visits app and authenticates with a login form which lies in ASP MVC app and generates a cookie.
Now I've decided to use AngularJs to add a couple features which made me use $resources and Web API 2. However, those features are only available if user is authorized.
To the problem: Now I must use a token for each request to the Web Api 2 to access different methods within controllers. This means I must login the user again but this time through AngularJs. Using /token route.
How would I do this?
Should I take the cookie, check credentials in it and send it as a authentication request?
Can I do something within the form authentication, in the same method, in the Asp MVC app?
Please help me, this gave me a lot of overhead. Walking from a simple app to this in 30min. Can't even get my head around all stuff in the authentication.
Regards!
My WebAPI supports both token and cookie auth.
During startup I register the authentication like this:
private void ConfigureAuth(IAppBuilder app)
{
//Token
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
});
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnApplyRedirect = ctx =>
{
// this is to ensure that a 401 response is sent if the
// user is not authenticated, rather than redirecting to
// a logon page.
}
},
CookieDomain = ".example.com" //might not need to set this
});
}

How to build secured api using ServiceStack as resource server with OAuth2.0?

I have build a OAuth2.0 Authorization server using dotnetopenauth that will manage authentication, authorization, and assign accessToken to the caller. The caller will use the access token to access the api (webservices) at resource server.
If follow the sample provided by dotnetopenauth in Resource Server, api that builded using WCF can be authenticated by OAuthAuthorizationManager
If using ServiceStack to build my api in Resource Server, how to build the authentication process that verify the incoming api request based on assigned OAuth2.0 access token? The functionality should similar to OAuthAuthorizationManager in the dotnetopenid sample and not based on login session.
Just some update
I didn't use the AuthenticateAttribute or RequiredRoleAttribute from ServiceStack.ServiceInterface.
I create 2 custom RequestFilterAttribute to replace the functions provided by AuthenticateAttribute and RequiredRoleAttribute.
In each custom RequestFilterAttribute's Execute method, I'm using method in dotnetopenauth to verify the access token.
//httpReq==req from Execute(IHttpRequest req, IHttpResponse res, object requestDto)
The code for the access token verification as following, reference the relevant documentation from both servicestack and dotnetopenauth for more info. ResourceServer is class from dotnetopenauth
HttpRequestBase reqBase = new HttpRequestWrapper((System.Web.HttpRequest)httpReq.OriginalRequest);
var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(AuthorizationServerPublicKey, ResourceServerPrivateKey));
IPrincipal ip = null;
resourceServer.VerifyAccess(reqBase, out ip);
If the ip is null then not authenticated, if not null, the incoming request is valid and can use the ip to check the role e.g. ip.IsInRole(requiredRole)
I'm not sure this is the correct way to do the checking or not, but it's works for me. Any better solution are welcome.

How to develop user-authenticated REST service with Azure ACS

I'm developing a REST service that uses MS Azure Access Control Service for authentication. If the examples are any indication, the typical way to secure a REST service this way would be to provide a global username and pw, private key, or X.509 cert for the protected service. However, I want to use the passive user login mechanism on a mobile device with a flow more like the following:
Unauthenticated user attempts to access protected service from app
Mobile app redirects to browser app (or embedded browser)
User selects identity provider to use for login (facebook, google, etc.) from ACS login page
User enters credentials for identity provider
Browser redirects back to app
App somehow gets the SWT token to use with subsequent REST requests.
I'm stuck at about step 5--getting the SWT token, and the existing examples I've found don't seem to address this scenario. In addition, I'm actually trying to build a proof of concept with a desktop client in WPF, which may complicate things. Can anyone suggest a specific tutorial or a path to pursue that uses the per-user authentication vs. per-service? Thanks.
EDIT:
As I'm digging into this deeper, I've realized that the examples posted below (and most others) are based on OAuth WRAP, which has been deprecated in favor of OAuth 2.0. Can anyone suggest a more up to date reference? Googling has turned up http://blogs.msdn.com/b/adventurousidentity/archive/2011/09/18/acs-v2-oauth-2-0-delegation-support-explained.aspx and http://connect.microsoft.com/site1168/Downloads/DownloadDetails.aspx?DownloadID=32719 but they're not the most intuitive.
You should look into the ACS Windows Phone sample:
http://msdn.microsoft.com/en-us/library/gg983271.aspx
Here instead of using Silverlight you will be using WPF. Most of the code should be re-usable. Note that since you are using WPF you will need to register your own object for scripting e.g:
[ComVisibleAttribute(true)]
public class NotifyHandler
{
public void Notify(string notifyString)
{
// Here I have the token.
}
}
this.webBrowser1.ObjectForScripting = new NotifyHandler();
Update:
The sample above uses OAuth Wrap to contact the secured service. If you would like to use OAuth2 you should change the way the "Authorization" header set:
OAuth WRAP case:
WebClient client = new WebClient();
client.Headers["Authorization"] = "OAuth " + _rstrStore.SecurityToken;
OAuth2 case:
WebClient client = new WebClient();
client.Headers["Authorization"] = string.Format("OAuth2 access_token=\"{0}\"", token);
You can use the "Simple Service" sample as a guide to implement your token validation in your REST service:
http://msdn.microsoft.com/en-us/library/gg185911.aspx
Yet if you would like to implement a more complete sample you can look at how CustomerInformationService is protected in the CTP version 1.4:
https://connect.microsoft.com/site1168/Downloads/DownloadDetails.aspx?DownloadID=35417
Take a look at this one:
WPF Application With Live ID, Facebook, Google, Yahoo!, Open ID
http://social.technet.microsoft.com/wiki/contents/articles/4656.aspx

Resources