How to store user credentials in an ASP.NET MVC website - wcf

My settings is as follows:
I have an MVC web application (EbWebApp) which has a service reference to an WCF service named EbServiceApp. For authentication purposes I implemented a forms authentication scenario:
The user logs on to the web site, and then in turn I authenticate the user to the web service (using forms authentication) too. For this I created another web service named AuthService.
Everything works just fine but when the forms authentication ticket expires for the web service I would have to relog on the user to the webservice without asking for username and password (this scenario can happen for example if I set a persistent cookie on the website for the user). I don't know how could I store the user's credentials to be available for reconnection to the web service.
Any help is appreciated.

Warning! Warning! Warning!
Whenever you think "How can i store the users credentials so i can automatically log them in later?" then you are doing something very dangerous. If you can log them in later, then someone can steal those credentials. It's ALWAYS a bad idea.
If the forms authentication ticket expires, then only the end user should be able to log himself back in. Otherwise, you're defeating the purpose of a ticket expiry. If you want the ticket to last longer, then just set its expiration to be longer.

Related

Can AD provide my Win desktop application with credentials for my web services?

I have a working c#/dotnet Windows desktop application that does its work by hitting various web services in my web application. When the desktop application starts up, it prompts the user for username / password and then hits my login web service, which returns a session token.
I have a large-org customer with many users. That customer wants to provide authentication / authorization for my combined desktop / web application directly from their domain controller. They want single signon, so my desktop app doesn't prompt their users for usernames and passwords.
How can my desktop application retrieve a usable authentication / authorization token from Windows (maybe from the user's Security Principal object)? How can my web application validate that token so it can trust the desktop application and send it a session token?
(My web application runs in my environment, not in the customer's domain.)
With pure-web-app customers I do this successfully with SAML2 and Active Directory / Federation Services. The SAML2 dance gets my user's browser to POST a request to the customer's AD/FS server, which then POSTs a signed response back to my web app.
But I can't figure out how to do it cleanly from a desktop application. Any wisdom?
You can check this samples in github (by jelledruyts): Modern claims-based identity scenarios for .NET developers
It has samples of authentication and authorization using Azure Active Directory and/or Windows Server Active Directory Federation Services.
I suggest read this article Digital Identity for .NET Applications. It's a little old but is a good overview/review.
Tokens come in many different formats. For today’s .NET applications,
however, three kinds of tokens are most important. They are the
following:
User name/password token—This very simple token contains only two
claims: the name of some subject and that subject’s password.
Kerberos ticket—More complex than a user name/password token, a
ticket includes a subject’s name, the name of the subject’s Windows
domain, and other information. Kerberos tickets that are issued by
Active Directory also include an extension that contains security
identifiers (SIDs) that identify the subject and the groups to which
this subject belongs.
SAML token—The Security Assertion Markup
Language (SAML) is an XML-based language that is owned by the OASIS
multivendor standards group. Unlike the other token types that are
described here, a SAML token doesn’t have a fixed set of claims
defined for it. Instead, this kind of token can contain any claims
that its creator chooses.
As soon as the claims are available, they can be used by Windows, the
application, or both. The most common uses of claims include the
following:
Authenticating the user(...)
Making an authorization decision(...)
Learning about this user(...)
Kind of Authentication:
Domain Based Authentication (eg Kerberos tickets):
A domain-based application accepts only a single token format with a
fixed set of claims. One common example is a Windows application that
accepts only Kerberos tickets. This kind of application is easy to
create, and it works well inside a single Windows domain. The problem
is that this simplistic approach to digital identity is no longer
sufficient for many applications
Claim Based Authentication (eg. SAML tokens):
Unlike a domain-based application, a claims-based application can
potentially accept multiple token formats with varying sets of claims.
The token formats and claim sets that this application accepts are
determined by the application itself.
Identity Technologies
Active Directory (AD) Domain Services (full-featured directory service, token source for Kerbero tickets, etc)
Active Directory Federation Services (ADFS) (support for claims-based applications, token source for SAML tokens
Windows CardSpace
Active Directory Lightweight Directory Services (subset of AD services)
Identity Life-Cycle Manager (ILM) (synchronization between different identity stores)
Windows Authorization Manager (tools for RBAC - role-based access control)
Active Directory Rights-Management Services (RMS)
Because AD Domain Services implements Kerberos, the default token in a
Windows environment is a Kerberos ticket. To use this default, an
ASP.NET application specifies Windows Integrated Authentication, while
a WCF application uses an appropriate binding, such as NetTcpBinding.
In either case, the following figure illustrates how a Windows
application with clients in the same domain might use a Kerberos
ticket and AD Domain Services
First versions of AD FS only support SAML with web clients.
ADFS 1.0, supports only browser clients—a restriction that’s scheduled
to change in the technology’s next release.
Hope it helps.
I should preface this with the fact that I've never done this, so I can't give you exact code, but I can point you in the right direction.
You should be able to do this with ADFS and Windows Integrated Authorization (WIA). In a "pure web app", the browser sends the credentials of the currently-logged-on user during the authorization step. In your case, your desktop app needs to do everything that the browser would normally do. Either way, the setup on the web service side should be exactly the same.
In C# with HttpClient, this is the important part:
var httpClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true
});
Then, whenever your httpClient sends a request that is challenged with a 401 response, it will automatically resend the request with the user's Windows credentials. This is exactly what a web browser would do. So use that when you get the token.
You may have to send a user agent string in the request, since ADFS seems to limit WIA to certain agents.
Once you have a token, then use the token in your requests to the web service.
The key is that you're replicating what a browser would do. So if you have trouble setting up what the HTTP requests should look like, then access a GET request in your API from a browser and use the browser's dev tools to inspect exactly what the traffic looks like, and use that information to replicate the same request in your code.

Validate external token asp net core

I'm doing a mobile app in Xamarin Forms, which should be able to connect to an ASP.NET core web service (API). I also want the information on the web service to be secured by limiting it to Microsoft account signed-in users. The idea I had was to send the user's credentials and retrieve back the security token from the Microsoft graph within the mobile app. Afterwards, the user would send that same bearer token to the web service, which checks its validity, and grants the requested information only if the validation is successful.
I am new to web development, so first of all, I want to ask if I am using a good approach for my project (if not, what do you recommend?).
If it is, how should I set up the ConfigureServices function in my Startup class? When I include the [Authorize] tag in the controllers, the service crashes, telling me I should define an authentication scheme. I don't need authentication, only authorization (since authentication is done from the mobile app), Since these two are handled independently in asp.net core, I added a dummy jwt authentication scheme as a placeholder. However, when I send an http request with the security token from my mobile app, it gives me a 401 unauthorized error, telling me I'm sending an "invalid token" (this token works fine when connecting to the Microsoft graph).
I've searched in countless documentations, but all of them only consider scenarios in which the authentication is done within the web service, and not externally, like me.
Any help is appreciated

Getting started with Microservices architecture

I'm very new to Microservices, and I would like to model something simple on paper: An application that allows users to login and upload photos (for sake of example).
I assume I would need:
Login service
User service
Pictures service
Can anyone assist with describing what the APIs would look like?
Login Service:
(POST) Login?user=username&pwd=password - Logs a user in
User Service:
(GET) User&user_id=123 - Gets the specified user
(POST) User - Creates new user
(POST) User&user_id=123&name=John - Updates existing user
How would a delete look like in this example
Of course, the photos would follow similar suit to the User Service.
However, I'm having a difficult time understanding how, say, the Login service will be used? Does this mean we have to call the login service every time that we need to authenticate a user? Or what would the general interaction be?
Thanks for any insight
For securing APIs the de facto approach is to do something like this:-
Authentication
Authenticating a user usually happens once per session - where session generally refers to a period of time in which the user is automatically logged out if the client is inactive for a specified period.
For example, if using Enterprise Java, you would usually configure your application server to timeout the HttpSession within a certain period of inactivity. You would authenticate the user - usually by comparing basic authentication credentials (username/password) against some profile you stored for them after they registered (using some Registration service). As part of authenticating a user, a HttpSession would be created and the user's ROLE is stored and checked on each request to check if the session is still valid. If the session has timed out, then the user needs to be directed to the authentication service again.
If using a stateless framework (no session hanging around between requests) then you would usually pass some token back and forth for each request and have some sort of validation mechanism ie. user profile stored in cache.
Think of authentication as ONCE PER SESSION.
Authorization
For each request (assuming the session is still valid) you would check that the user's ROLE has the necessary privileges to carry out the action requested.
OAuth - an example of an Authorization framework) - is generally designed for authenticating third-party clients to access one of your user's resources but if you have a look at OAuth 2 then it will give you an understanding of the token-based approach at authenticating a user/client between requests.
Think of authorization as EVERY REQUEST.

WCF Authentication -- Authenticate user/pass one time, then authenticate some other way afterwards?

Basically, I have the following scenario and information:
We're using HTTPS.
We want to authenticate a user by user/pass when they first log in.
After they are authenticated, I want any future calls to OTHER services (not the login service) to use the username and some sort of session (in case the password changes in the middle of a session).
I want to make sure my sessions can timeout and control them in a way that if a user tries to call a service and they don't have a session they get an error (cause they haven't logged in). Not sure if there's a WCF built-in way to do sessions this way or if I'll have to do something customized with a database.
I think we want to use WSHttpBinding (not BasicHttpBinding), 90% sure on this.
I just can't seem to figure out how to do this. Often time's I'll find information on the client code doing client.ClientCredentials.UserName.UserName = username and client.ClientCredentials.UserName.Password = password. But, that just doesn't work because what is my server checking against? I'm trying to grab that info and validate it against a database of user/passes. I'm not looking to use Windows Authentication or that sort (because I don't care who is logged into the computer, just who is logging into the app).
You want to use a Secure Token Service (STS) to authenticate and get a Security Token (maybe SAML) back that identifies the user which can then be passed to your other services and they can just use the identity information to identify and authorize because they trust the STS has verified the user's identity up front.
This is a large subject to discuss, so I suggest searching for WCF STS and doing some more research, but that's definitely the direction I'd recommend going. If you're going to build your own STS implementation, I also recommend looking into using the Windows Identity Foundation (WIF) components to ease your development efforts.
Here's the download link for WIF v1.0 which is the latest version at the time of this answer.

OpenID authentication and API access

OpenID authentication is inherently browser based. If I wanted to allow an OpenID user to authenticate against an API for use in alternative clients, is there an accepted best practice for that?
So if a user tried to log in with their OpenID into an iPhone app, for instance, how would that work? The only thing I can think of generating an API token of some sort for them and get the user to manually enter it somewhere. This approach is not user friendly.
This is the way sites like Basecamp work, but it still seems clunky to me.
The problem you're seeing is not unique to OpenID. Any password-less authentication scheme can have this problem. OAuth (http://oauth.net/) is a solution that is an open standard that is quickly gaining traction on a lot of web sites. It is totally independent of how the user authenticates, so their OpenID Provider does not need to support or even be aware that your site (the "service provider" in OAuth terms) is using OAuth. Your API client can be web based or even a local application!
The process would be something like this:
Roles:
the user: someone who has an account with your web site.
service provider: your web site, which has a programmatic API that requires some credential to access.
consumer: the client, whether web or local application, that needs access to the service provider's API.
Flow:
The user is at the consumer. He indicates he wants to access data at the service provider.
The user is either redirected (if the consumer is a web site) or a browser is popped up (if the consumer is a local app) and the user sees the service provider web site.
The user is either already logged into the Service Provider via a persistent cookie, or the user must first log into the Service Provider however that is done (OpenID in your case).
The Service Provider then asks the user: "Consumer (some consumer) wants access to your data (or our API, or whatever). Do you want to authorize this? (yes/no)
User confirms, and the browser window closes or is redirected back to the Consumer site.
Via some OAuth protocol magic, the consumer now has a secret credential that it can use to access your API and access whatever user-private information you just authorized.
Obviously I can't include the whole OAuth spec here, but you can see hopefully from the above that this should solve your problem. OAuth libraries exist to make adding support for it easy.
If you happen to be using ASP.NET, I suggest http://dotnetopenid.googlecode.com/ as it recently added OAuth support (v3.0 beta 1).
Neither OpenID nor OAuth define how a user authenticates. They define how the consumer directs the user agent to the authentication provider, how the user agent is directed back, and how the consumer can verify the identity that the user authenticated as.
The actual method used to authenticate is out of band for both schemes.
There are differences between OpenID and OAuth, but both require that the consumer use HTTP redirects and callback URLs. They're both browser based. If your app speaks HTTP, it can do either. However, a main point is that the user is only entering credentials into a trusted app.
What you want is not possible with OpenID. OpenID is based on the premise that you (the iPhone app) only want to know about your users that their OpenID-provider trusts them. They never authenticate themselves to you.
Good OpenID-providers in fact even prevent that you mediate the authentication process (as this would expose users to a possible attack - by you!): they demand that users login with them directly and refuse login-by-referral.
See: this related question
The problem is that the openid spec has no standard provision for authentication with the provider, so the provider can elect that authentication happens via a phone call or whatever.
Hopefully more providers embrace OAuth. Alternatively you could hand code the authentication for a few of the bigger sites.