WinForm app communicating with ASP.NET Mvc or WebService - asp.net-mvc

Is it possible to have a WinForms application make a simple call to an Mvc app over the wire to carry-out a simple query (into a controller > service > repository)? I'm wondering whether it should provide a service api controller, separate to the rest of the application which spits out the Json to the WinForms application, or should it go the WCF/WebService route?
It needs to be able to authenticate too so the end solution is secure. As the WinForms app needs to poll the end-point, I don't want to send the username/password in each request. Can there be some provision for a session on the end-point which times-out and then requires a re-login from the client?

Yes, you can use the System.Net.HttpWebRequest and System.Net.HttpWebResponse classes to create an HTTP client. See here for an example.
Web apps do have a session timeout which starts counting when there is no activity on a session. So, if you do not want to be re-authenticating on every request, you will need to echo the cookies that the server sends to you in HttpWebResponse back to the server with the next HttpWebRequest, so that the server knows your session and keeps you logged in. If you erase the cookies, you will need to re-authenticate. If you do not interact with the server for a while, (usually about 20 minutes,) you will also need to re-authenticate. (Assuming that your WinForms application will not check the 'remember me' checkbox on the login form.)

Related

Custom authenticator for 2FA with lighttpd

I have a web application which currently uses lighttpd with mod_auth and the htdigest method for authentication. I want to expand the web apps functionality to allow for 2FA. If I understand correctly, what happens for htdigest authentication is the following:
The browser requests a website from the server
The server responds with "authentication required"
The browser shows the user a window asking for username/password and sends this information to the server
The server serves the webpage
If I understand correctly, the server caches this auth info and automatically sends it for following requests.
Now, I want to add 2FA. I found out that I can use fastcgi to build a custom authorizer. Can I use this to do 2FA? How can I ask the browser to provide the user with a possibility to enter the OTP? It's no use to cache the OTP and send it with every request, so I guess I need to store a session token or something which the browser should send with every following request?

Is there an OpenID Connect grant type or mechanism for an app to poll for the auth-code when redirect_uri doesn't apply?

If you have an on-device application (e.g. desktop program, mobile device app) you can use OpenID Connect with some caveats:
Using Resource Owner Credentials (grant_type: password) is the simplest, but might not be possible if the authentication server operator won't let you use that grant-type because of trust reasons (i.e. they don't want you collecting the user's username+password yourself) - or if they have a dynamic or custom authentication UI that would be hard to replicate in a native app.
With the interactive flows (implicit, hybrid) the authentication sever's authentication page is shown in an in-app web-view. Most users will have no idea that the application can snoop on the authentication page and capture their username and password, especially on mobile devices - but this way the application code can easily capture the authorization code and/or access token, and automatically dismiss the web-view without any additional user interaction. (I'm surprised I haven't heard of more cases of users' details being captured by malicious apps this way.)
...so the advice is to always open the authentication page using the system's web-browser, but on the Windows desktop there is no good, standard way for the system web-browser to return the server response to the application code, though there are a number of approaches currently in use:
The authentication success page instructs the user to copy and paste a blob of text (containing the authorization code or access_token response) back into the desktop application.
Show the page in an app-hosted web-view, as per the notes above.
If the authentication process always only needs a username and password (for example) the application could still capture the user's username and password with its own UI and then make its own HTTP requests to make it seem like a user's web-browser session, and get the authorization code and/or access_token that way.
On Windows only:
Have a small utility program authHelper.exe that when invoked forwards its command-line arguments to a named-pipe in the user's session.
The main client-application will register authHelper.exe as a temporary URI scheme handler in the per-user HKCU\Software\Classes key, e.g. my-application: such that the contents of any my-application: URI are passed as arguments into authHelper.exe.
The URI passed to the system web-browser to open the authentication page has the redirect_uri parameter set to my-application:, so after the user authenticates in the browser, the browser will request the custom URI scheme which is handled by Windows, which invokes authHelper.exe "access_token=..." which then sends the data down the named-pipe to the running application.
If the user doesn't have permission to write to their own HKCU\Software\Classes key, or if they're using a version of Windows that doesn't support custom URI scheme handlers with EXE registrations then this doesn't work.
Windows UWP applications can also use the Web Authentication Broker.
I was wondering if a different approach could be used: why can't the application simply poll the authentication server for the status of the authentication attempt? Or does this approach already exist, and if so, what is the name of the flow or grant?
Here's the flow I'm proposing:
When the user wants to authenticate, the application opens the system web-browser as before, but with another parameter for a one-time-use opaque ID provided by the application.
As soon as the system browser is open, the application makes requests every 500ms or so (i.e. a polling loop) to the authentication server using its own HTTP client that asks for the status of the active authentication attempt associated with the same opaque ID as before.
The initial few responses from the authentication server to the application will presumably be status: pending, but eventually after the user successfully authenticates within a timeout window then the application's poll request would indicate a successful attempt and also contains the access_token or authorization code as is applicable. If the user failed to authenticate (e.g. 3 incorrect attempts) or left the window open long enough causing a timeout then the poll response would indicate failure.
Does this already exist and does it have a name? Are there any potential security risks or vulnerabilities with this approach?
It exists and has a name, "OAuth 2.0 Device Flow for Browserless and Input Constrained Devices", but is not yet fully standardized, see: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-device-flow
Google also implemented this flow avant-la-lettre in a vendor-specific way:
https://developers.google.com/identity/protocols/OAuth2ForDevices

SignalR - The connection id is in the incorrect format when using Windows and Anonymous authentication

I use SignalR 1.0.1 as a chat core for ASP.NET MVC3 application. Using IIS 7.5
There are two methods in MVC controller which provides access to chat views:
1. First method is public, allowing anonymous users to chat - no authorization.
2. Access to second method is restricted with [Authorize] attribute, for domain users - chat agents.
There is no explicitly specified authorization in the Hub.
For this scenario I involved both Windows and Anonymous authentication on IIS.
I also implemented custom Role Provider, which operates only in memory - not persisting anything to database.
What happens is that using '[Authorize]' attribute in controller method leads to responsing 500 from Hub, both when call is coming from authorized view, and the anonymous one:
Request (send is Hub method for sending messages):
http://localhost:8101/signalr/send?transport=serverSentEvents&connectionToken=VIXEZzWQSn5SNlA8RUy4iaOPDFdvuPBjMvFBiG2FLfvfxF347XHwtapsEV5ndU4OEI0Xb64W2ZRXTqwBiL2CXg2_JlTaTJ2RnVOj4bjvx6tQaYhAqTaXs9k2853GYqzd0
Response:
The connection id is in the incorrect format.
Server stack trace:
at Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext context, String connectionToken)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary2 environment)
at Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary2 environment)
at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()
at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData)<br/><br/>
But notice, that connecting to Hub works fine, returns 200 OK:
http://localhost:8101/signalr/connect?transport=serverSentEvents&connectionToken=dYOwFxa1mkgdpzw-jitRpWq9oxRlrTet8U_dAzWjFQEdGNJfVXeG7Op0NZZwvznxeNdJCuPT75CKzQqI9HRPThV3uEDt-Z2qtIl9E02gF481&connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&tid=9
I found little similiar thread here on stackoverflow:
signalr The connection id is in the incorrect format
from which I understand, that when invoking my Send method, the Hub is processing request with Identity different than the one used to connect to Hub, OR Hub's GetConnectionId finds, that user is actually not authorized - but how it checks that assumption, when there is no authorization specified on the Hub itself?
Can someone put some light on this?
Thanks in advance :)
SignalR signs both your connection id and your Identity together in order to create a new connectionToken every time you start a new connection. This connectionToken is then sent to the SignalR client as part of the negotiate response.
Every time you make a request to SignalR, whether it be a connect, reconnect, or send request, SignalR verifies that your connectionToken matches both your client's connection id AND Identity.
The connectionToken is essentially a CSRF token used in order to prevent attackers running third-party websites from surreptitiously making SignalR requests on behalf of shared clients. Obviously this doesn't help if you've enabled SignalR's cross-domain support, but the connectionToken still works the same in this case.
Taylor's answer was correct. You should stop and then start your SignalR connection when your client's Identity changes. This will force a new negotiate request which will give your client a new connection id with a new connectionToken signed with your client's updated Identity.
P.S. The server-sent events connect request isn't failing because it was established before your client's Identity was changed. The connectionToken is only checked at the request is received, but server-sent events keeps the response open indefinitely.
That's all true what you said and it actually takes place in my issue.
But I also found the the root cause:
One of main assumptions during design was to allow both anonymous users to use the chat without need to sign-in and the back-end users (agents) to sign-in to restricted area of chat using their Windows credentials.
So on the IIS manager I enabled both Anonymous authentication (allowing anonymous users to use the chat) and the Windows authentication (allowing agents to access using their Windows credentials).
MVC application is configured to use Windows authentication - the [Authorize] attribute mentioned in question, but only to restrict access for agent's view of chat.
What actually happens with above configuration is:
1. When client (agent) requests restricted View (let's say it's /Chat/Agent) the [Authorize] attribute initializes authentication (Windows)
2. Client-side Javascript requests Negotiate, what generates connectionId and binds it with client's Windows Identity
3. Here is the tricky part: Because Hub not uses any authentication explicitly, calling send method does not result in any authentication request - IIS Anonymous authentication takes precedency before Windows authentication, and send request is sent with anonymous Identity - but in Hub actual connectionId is related to Identity passed in point 2.
This scenario leads to situation you described - connect is called with different Identity than send and Hub returns The connection id is in the incorrect format.

CAS and Spring-Security: regularly check if a ticket has expired

I have a CAS-Server and a Client configured via Spring-Security. Single Sign On and Single Logout are working fine so far.
I'm still facing an issue with session timeout. As I understand the ticket expiration policy is not affected by idleness of the secured CAS client side session. So a client must actively revalidate a ticket to see if it has expired and is not being posted the expiration event by the CAS server as it is the case when a single logout is performed.
To force my spring secured client to regularly check for the expiration of the ticket I might set the session timeout to a low value like a minute or so. But that has the drawback of all my session data to be removed. Not very user friendly.
Is there a way to tell spring-security to regularly check if a ticket is still valid without destroying the user session first?
I would be pretty confident on the Javascript solution as it's just a simple check to force local logout. Though, it needs to customize your CAS server, that you cannot do.
You have the solution of having a shorter session on application side to force regular re-authentication, but this means that you will invalidate often your application session and recreate it.
A better solution can be based on the gateway parameter of the CAS protocol : using this parameter will not produce a service ticket if you are not SSO authenticated. So you could have :
an application filter which, every 5 minutes, saves the current url, triggers a CAS round-trip with gateway=true and a specific service : http://myserver/myapp/checkCasSession
a specific url : /checkCasSession : if it receives a service ticket, everything is ok, the CAS session is still valid, it just restores the original url. If there is no service ticket, the local session must end and a local logout is triggered.
I think there is no such way. Spring Security and Spring Security Cas are implemented as a set of Servlet API filters / listeners. So Spring Security Cas works only during some Http request / Session event processing. I do not view any dependency on some scheduling library for spring-security-cas.jar.
It's not an easy problem you can address out of the box with Spring Security. You need to work on both sides : client and server. I would :
create a controller on CAS server side which returns a JSON indicating if the CASTGC has expired or not
every 5 minutes (for example) and each time an application page is displayed, add some javascript to call this specific CAS controller and if the CAS session has ended, ends also the application session.
You need to call the CAS server from front channel as the CAS session is held by the CASTGC cookie.
You have two sessions : the application one with its idle timeout and the CAS one with idle / hard timeouts. After having accessed the application through CAS login, the application session lives on its own and can last more than the CAS session. It's generally not a problem. What use case do you want to handle ?

Handling cookies with Flex for Authentication

I'm using Flex 4(beta2) with Ruby on Rails 2.3.5 and using RubyAMF to transfer data back and forth between Flex and server.
I set up Authlogic on the Rails side for authentication.
I wasn't sure what's the best method to handle user sessions. I know this is done automatically with Rails by sending session id with cookie which Rails use to authenticate the user.
What do you suggest the best way to do this with Flex?
I thought of couple of options:
1. Manually fetching the cookie from the browser and then figuring our a way to send that to the server with every request I send.
2. Handling sessions expiration and flow on Flex side by manually expiring the session
Do you have other suggestion or recommendation?
Thanks,
Tam
Network requests in Flash use the browser networking stack so cookies in Flex work just like any other browser application. Usually authentication in Flex is no different than it is with a standard web application. Send credentials to the server which it correlates with a session id. Every subsequent request (RemoteObject, HTTPService, etc) also sends that session id.
We have seen that the flash plug-in propagates the session cookie when we do blazeDS (http) remote calls
In the past we have worked with BlaseDS and HTTPServices. In both the cases the request is sent to the server over HTTP. Our server stack as Java (JBoss to be specific).
We noticed that the flex client used to send the session information with the requests to the server. We used same information to store and fetch Principal on the server.
In one case, we propagated the token to the client. This was to avoid multiple submits for same requests - hence we used the common HTML submission approach of token generation where with every response carries with itself a new token and the client has to sent it back to the server for executing the next request.
For the session expiration, there is a good chance that a user is working on the client for any local needs and not working with the server which may have caused a expiration on the server without impacting the server. In this case, we disabled the session expiration on the server and wrote custom code to handle events - keyboard and mouse on the flex client. If the application was not used for a specified time, the flex client would expire both the sessions i.e. local and server
What do you suggest the best way to do this with Flex?
$loggedIn=Authenticate::isAuthenticated();
if(!$loggedIn)return false;
$user=Authenticate::getAuthUser();
First Authenticate the user and if he is logged in create the session. Include this in your every PHP or Ruby file, and check it. Send the Session ID to Flex to maintain the state and you set the time for your session to expire.
The above code does check, whether the user is authenticate to access the PHP or ruby class files.

Resources