Taylohtio/GeneralSSO/GeneralSSO.Server/Layouts/Taloyhtio/OAuth/Authenticated/Authorize.aspx.cs

200 lines
8.2 KiB
C#

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<IClientRepository>();
this.clientAuthRepository = ServiceLocator.Current.GetInstance<IClientAuthorizationRepository>();
}
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;
// }
}
}