using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Net; using System.Threading; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth2; using DotNetOpenAuth.OAuth2.Messages; using Microsoft.Practices.ServiceLocation; using Microsoft.SharePoint; using Taloyhtio.GeneralSSO.Server.Layouts.Taloyhtio.OAuth.Authenticated.App_LocalResources; using Taloyhtio.GeneralSSO.Server.CodeFiles.Common; using Taloyhtio.GeneralSSO.Server.CodeFiles.Entities; using Taloyhtio.GeneralSSO.Server.CodeFiles.Infrastructure.OAuth; using Taloyhtio.GeneralSSO.Server.CodeFiles.Models; using Taloyhtio.GeneralSSO.Server.CodeFiles.Repositories; namespace Taloyhtio.GeneralSSO.Server { public partial class Authorize : Page { private IClientRepository clientRepository; private IClientAuthorizationRepository clientAuthRepository; protected AuthorizeModel Model { get; set; } public Authorize() { this.clientRepository = ServiceLocator.Current.GetInstance(); this.clientAuthRepository = ServiceLocator.Current.GetInstance(); } protected void Page_Load(object sender, EventArgs e) { if (HttpContext.Current.User == null || HttpContext.Current.User.Identity == null || !HttpContext.Current.User.Identity.IsAuthenticated) { throw new Exception("User is not authenticated."); } if (!this.IsPostBack) { this.view(); } else { this.authorize(); } } private void authorize() { var authServer = new AuthorizationServer(new AuthorizationServerHost()); var authRequest = authServer.ReadAuthorizationRequest(null); if (authRequest == null) { throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request."); } bool isApproved = bool.Parse(this.Request.Form["IsApproved"]); IDirectedProtocolMessage response; if (isApproved) { var client = this.clientRepository.GetByClientId(authRequest.ClientIdentifier); if (client == null) { throw new Exception(string.Format("Client '{0}' not registered.", authRequest.ClientIdentifier)); } string userName = Utils.GetUserName(HttpContext.Current.User.Identity.Name); this.addClientAuthorization(authRequest, userName); response = approve(authServer, authRequest, userName); } else { response = reject(authServer, authRequest); } //return authorizationServer.Channel.PrepareResponse(response).AsActionResult(); authServer.Channel.PrepareResponse(response).Respond(HttpContext.Current); Response.End(); } private IDirectedProtocolMessage reject(AuthorizationServer authServer, EndUserAuthorizationRequest authRequest) { var msg = authServer.PrepareRejectAuthorizationRequest(authRequest, null); msg.Error = Authorize_aspx.Denied; return msg; } private IDirectedProtocolMessage approve(AuthorizationServer authServer, EndUserAuthorizationRequest authRequest, string userName) { // In this simple sample, the user either agrees to the entire scope requested by the client or none of it. // But in a real app, you could grant a reduced scope of access to the client by passing a scope parameter to this method. //response = authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, Thread.CurrentPrincipal.Identity.Name); var response = authServer.PrepareApproveAuthorizationRequest(authRequest, userName, null, null); return response; } private void addClientAuthorization(EndUserAuthorizationRequest authRequest, string userName) { if (authRequest == null || string.IsNullOrEmpty(userName)) { return; } var client = this.clientRepository.GetByClientId(authRequest.ClientIdentifier); if (client == null) { return; } // create automatic client authorization for specified amount of hours //int lifeTime = this.getTokenLifetime(); var now = DateTime.UtcNow; var clientAuth = new ClientAuthorization { Client = client, CreatedOn = now, UserId = userName, Scope = OAuthUtilities.JoinScopes(authRequest.Scope), // currently client authorizations are permanent ExpirationDate = null/*now.AddHours(lifeTime)*/ }; this.clientAuthRepository.Save(clientAuth); } private void view() { var authServer = new AuthorizationServer(new AuthorizationServerHost()); var authRequest = authServer.ReadAuthorizationRequest(null); if (authRequest == null) { throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request."); } // if user already authorized this app with the same scope, don't ask permissions again. // Currently we check the scope by equal operation. In future it can be changed to more // complicated algorithm using sub sets analysys (if currently requested scope is sub // set of existing authorization, then also no need to ask permissions again) if (this.alreadyAuthorized(authRequest)) { string userName = Utils.GetUserName(HttpContext.Current.User.Identity.Name); var response = approve(authServer, authRequest, userName); authServer.Channel.PrepareResponse(response).Respond(HttpContext.Current); Response.End(); } var client = this.clientRepository.GetByClientId(authRequest.ClientIdentifier); if (client == null) { throw new Exception(string.Format("Client '{0}' not registered.", authRequest.ClientIdentifier)); } this.Model = new AuthorizeModel { ClientName = client.Name, Scope = authRequest.Scope, AuthorizationRequest = authRequest, }; } private bool alreadyAuthorized(EndUserAuthorizationRequest authRequest) { // don't allow authorization with empty scope to be reused if (authRequest.Scope.IsNullOrEmpty()) { return false; } var client = this.clientRepository.GetByClientId(authRequest.ClientIdentifier); if (client == null) { throw new Exception(string.Format("Client '{0}' not registered.", authRequest.ClientIdentifier)); } string userName = Utils.GetUserName(HttpContext.Current.User.Identity.Name); var validAuthorizations = this.clientAuthRepository.GetNotExpiredBy(authRequest.ClientIdentifier, userName, OAuthUtilities.JoinScopes(authRequest.Scope)); return !validAuthorizations.IsNullOrEmpty(); } // private int getTokenLifetime() // { // string lifeTimeStr = ConfigurationManager.AppSettings["AutomaticAuthTokenLifeTimeHours"]; // if (string.IsNullOrEmpty(lifeTimeStr)) // { // return Constants.OAuth.DEFAULT_TOKEN_LIFETIME_HOURS; // } // int lifeTime; // if (!int.TryParse(lifeTimeStr, out lifeTime)) // { // return Constants.OAuth.DEFAULT_TOKEN_LIFETIME_HOURS; // } // return lifeTime; // } } }