200 lines
8.2 KiB
C#
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;
|
|
// }
|
|
}
|
|
}
|