Authentication 未调用identityserver3自定义用户服务

Authentication 未调用identityserver3自定义用户服务,authentication,active-directory,identityserver3,Authentication,Active Directory,Identityserver3,[已编辑:添加用户服务代码] 当我的IdentityServer中的以下代码标记了ADUserService,并且未标记.UseInmemory(MemUser.TempUser)代码时,所有代码都正常工作 当InMemory被标记,并且两个ADUserService行未被标记(如下面的代码所示)时,将显示相同的登录屏幕,但这次失败。调试时,不显示日志,并且在登录期间不输入ADUserService,而仅在调用启动代码期间输入 我错过了什么吗?我做错什么了吗? //identityServer工

[已编辑:添加用户服务代码]

当我的IdentityServer中的以下代码标记了ADUserService,并且未标记.UseInmemory(MemUser.TempUser)代码时,所有代码都正常工作

当InMemory被标记,并且两个ADUserService行未被标记(如下面的代码所示)时,将显示相同的登录屏幕,但这次失败。调试时,不显示日志,并且在登录期间不输入ADUserService,而仅在调用启动代码期间输入

我错过了什么吗?我做错什么了吗?

//identityServer工厂
var factory=new IdentityServerServiceFactory()
//.UseInMemoryUsers(MemUser.TempUser)//修复:删除临时用户!!
.UseInMemoryClients(CrbAuthClients.Get())
.用于内存示波器(示波器。所有支持的示波器);
var userService=new ADUserService();
factory.UserService=新注册(解析器=>UserService);
//identityServer启动!!
var options=新标识服务器选项
{
SigningCertificate=Certificate.Load(),
AuthenticationOptions=新的AuthenticationOptions
{ 
SignInMessageThreshold=1//默认值为5,防止出现“标题过长”错误
},
工厂
};
app.UseIdentityServer(选项);
这可能是因为我使用Visual Studio及其IIS Express时,没有为IDServ3服务器(位于Nancy)或我的MVC客户端验证https

是否我需要添加CORS策略服务?我什么时候需要?我从一个单独的MVC项目和网站调用身份验证

factory.CorsPolicyService = new Registration<ICorsPolicyService>(new DefaultCorsPolicyService { AllowAll = true });
factory.CorsPolicyService=新注册(新的DefaultCorsPolicyService{AllowAll=true});
这可能是我以前在Mem用户中使用的一个问题,而现在某个地方仍然有某种缓存在使用它们吗?(我检查了bob secret,它在更改后停止工作,并在更改回内存用户时恢复工作)

-----编辑-----

也许是因为我没有使用ldapConnectionDelegate? 我需要吗

代码如下:

namespace Crb.Auth.AuthServer.Securing
{
    using System;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Threading.Tasks;
    using System.DirectoryServices;
    using System.Security.Claims;

    using System.DirectoryServices.AccountManagement;
    using IdentityServer3.Core;
    using IdentityServer3.Core.Services;
    using IdentityServer3.Core.Models;
    using IdentityServer3.Core.Extensions;
    using IdentityServer3.Core.Services.Default;

    using Serilog;

    // according to gist https://gist.github.com/rmbrunet/6c5c2ba2b8fb03fbc359
    // from rmbrunet on Stack Exchange here: https://github.com/IdentityServer/IdentityServer3/issues/1366

    // A slightly cleaner but less explicit approach (not used here) is in https://gist.github.com/tjrobinson/0ad6c790e90d7a385eb1
    // from rajarameshvarma on Stack Exchange here: https://github.com/IdentityServer/IdentityServer3/issues/995

    // Startup code is taken from the CustomUserService project in the IdentityServer3 Samples.

    public class ADUserService : UserServiceBase //UserServiceBase
    {
        static class ADAttributes
        {
            public static string SamAccountName = "samaccountname";
            public static string Mail = "mail";
            public static string UserGroup = "usergroup";
            public static string DisplayName = "displayname";
            public static string Department = "department";
            public static string StreetAddress = "streetAddress";
            public static string Phone = "telephoneNumber";
            public static string State = "st";
            public static string City = "l";
            public static string Zip = "postalCode";
            public static string Surname = "sn";
            public static string Givenname = "givenName";
        }

        const string ActiveDirectoryConnectionStringname = "CnnActiveDir";

        #region setup and construction
        //Func<string, string> _ldapConnectionDelegate; //Delegate that receives the domain and returns the LDAP connection string.

        // default ctor reads from connection string
        public ADUserService()//Func<string, string> ldapConnectionDelegate)
        {
            //_ldapConnectionDelegate = ldapConnectionDelegate;
            //Log.Debug("ADUserService called");
        }
        //.. region setup and construction
        #endregion

        #region authenticate with claims

        #region authenticate external - not supported
        public System.Threading.Tasks.Task<IdentityServer3.Core.Models.AuthenticateResult> AuthenticateExternalAsync(IdentityServer3.Core.Models.ExternalIdentity externalUser, IdentityServer3.Core.Models.SignInMessage message)
        {
            return Task.FromResult<AuthenticateResult>(null);
        }
        #endregion

        public Task<AuthenticateResult> AuthenticateLocalAsync(
            string userDomainAndName, // sometimes referred to as 'the subject'
            string password,
            SignInMessage message)
        {

            bool isUserValid = false;

            if (string.IsNullOrEmpty(userDomainAndName) 
                || userDomainAndName.IndexOf(@"\") < 1) // expected: some domain name given followed by a backslash
            {
                Log.Debug("Supplied username missing domain. Authentication denied.");
                return Task.FromResult<AuthenticateResult>(null); // Failed!! 
            }
            var split = userDomainAndName.ToLower().Split('\\'); //username assumed to be in the form domain\user
            string domain = split[0];
            string username = split[1];


            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
            {
                isUserValid = pc.ValidateCredentials(username, password);
            }

            if (!isUserValid)
            {
                Log.Debug("Authentication attempt failed for {0}", userDomainAndName);
                return Task.FromResult<AuthenticateResult>(null);
            }

            return Task.FromResult<AuthenticateResult>(
                new AuthenticateResult(subject: username.ToLower(), name: username));
        }

        #region pre-authenticate async - not supported
        public System.Threading.Tasks.Task<IdentityServer3.Core.Models.AuthenticateResult> PreAuthenticateAsync(IdentityServer3.Core.Models.SignInMessage message)
        {
            return Task.FromResult<AuthenticateResult>(null);
        }
        #endregion
        //..region authenticate
        #endregion

        #region profile

        public System.Threading.Tasks.Task<IEnumerable<System.Security.Claims.Claim>> GetProfileDataAsync(
            System.Security.Claims.ClaimsPrincipal principal,
            IEnumerable<string> requestedClaimTypes = null)
        {

            List<System.Security.Claims.Claim> claims = new List<Claim>(); //x null;


            string subject = principal.GetSubjectId();
            if ( ! string.IsNullOrEmpty(subject) )
                claims.Add(new Claim(Constants.ClaimTypes.Subject, subject)); // notice: idsrv3 short name convention as opposed to claims with full type

            SearchResult result = findUser(subject);
            if (result != null &&
                result.Properties.Contains(ADAttributes.Mail) &&
                result.Properties.Contains(ADAttributes.DisplayName))
            {
                claims.Add(new Claim(ClaimTypes.Email, (String)result.Properties[ADAttributes.Mail][0]));
                claims.Add(new Claim(ClaimTypes.Name, (String)result.Properties[ADAttributes.DisplayName][0]));

                if (result.Properties.Contains(ADAttributes.Surname))
                    claims.Add(new Claim(ClaimTypes.Surname, (String)result.Properties[ADAttributes.Surname][0]));

                if (result.Properties.Contains(ADAttributes.Givenname))
                    claims.Add(new Claim(ClaimTypes.GivenName, (String)result.Properties[ADAttributes.Givenname][0]));

                //Is there an address?
                if (result.Properties.Contains(ADAttributes.State)
                    && result.Properties.Contains(ADAttributes.StreetAddress)
                    && result.Properties.Contains(ADAttributes.City)
                    && result.Properties.Contains(ADAttributes.Zip))
                {

                    string state = (String)result.Properties[ADAttributes.State][0];
                    string street = (String)result.Properties[ADAttributes.StreetAddress][0];
                    string city = (String)result.Properties[ADAttributes.City][0];
                    string zip = (String)result.Properties[ADAttributes.Zip][0];

                    string address = string.Format("{0}, {1}, {2} {3}", street, city, state, zip);
                    claims.Add(new Claim(ClaimTypes.StreetAddress, address));
                }

                // Get roles from AD user groups
                var prince = principal.Identity as UserPrincipal;
                var groups = prince.GetGroups();
                foreach (var group in groups)
                    claims.Add(new Claim(ClaimTypes.Role, "dpn:" + group.DisplayName+",dtn:"+group.DistinguishedName ));

                claims = claims.Where(x => requestedClaimTypes.Contains(x.Type)).ToList();
            }

            return Task.FromResult(claims.AsEnumerable());
        }
        //.. region profile
        #endregion

        #region sign-out

        public System.Threading.Tasks.Task SignOutAsync(System.Security.Claims.ClaimsPrincipal subject)
        {
            return Task.FromResult(0);
        }
        //..region sign-out
        #endregion

        #region internals

        SearchResult findUser(string subject)
        {
            string[] a = subject.Split('\\');

            string domain = a[0];
            string username = a[1];

            string node = ConfigurationManager.ConnectionStrings[ActiveDirectoryConnectionStringname].ConnectionString;
                            //x _ldapConnectionDelegate(domain);


            using (DirectoryEntry searchRoot = new DirectoryEntry(node))
            {
                using (DirectorySearcher search = new DirectorySearcher(searchRoot))
                {

                    search.Filter = string.Format("(&(objectClass=user)(objectCategory=person)(SAMAccountName={0}))", username);
                    //search.PropertiesToLoad.Add( Constants.ADAttributes.SamAccountName );
                    search.PropertiesToLoad.Add(ADAttributes.Mail);
                    search.PropertiesToLoad.Add(ADAttributes.UserGroup);
                    search.PropertiesToLoad.Add(ADAttributes.DisplayName);
                    search.PropertiesToLoad.Add(ADAttributes.Surname);
                    search.PropertiesToLoad.Add(ADAttributes.Givenname);
                    search.PropertiesToLoad.Add(ADAttributes.Department);
                    search.PropertiesToLoad.Add(ADAttributes.StreetAddress);
                    search.PropertiesToLoad.Add(ADAttributes.Phone);
                    search.PropertiesToLoad.Add(ADAttributes.State);
                    search.PropertiesToLoad.Add(ADAttributes.City);
                    search.PropertiesToLoad.Add(ADAttributes.Zip);

                    return search.FindOne();
                }
            }
        }

        public System.Threading.Tasks.Task<bool> IsActiveAsync(System.Security.Claims.ClaimsPrincipal principal)
        {
            string subject = principal.GetSubjectId(); // this should return the "distinguished name" (sub.maindomain/username)
            SearchResult result = findUser(subject);
            return Task.FromResult(result != null);
        }
        //.. region internals
        #endregion
    }
}
名称空间Crb.Auth.AuthServer.Securing
{
使用制度;
使用系统配置;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Threading.Tasks;
使用System.DirectoryServices;
使用System.Security.Claims;
使用System.DirectoryServices.AccountManagement;
使用IdentityServer3.Core;
使用IdentityServer3.Core.Services;
使用IdentityServer3.Core.Models;
使用IdentityServer3.Core.Extensions;
使用IdentityServer3.Core.Services.Default;
使用Serilog;
//根据要点https://gist.github.com/rmbrunet/6c5c2ba2b8fb03fbc359
//来自Stack Exchange上的rmbrunet,此处:https://github.com/IdentityServer/IdentityServer3/issues/1366
//这里使用了一种稍微干净但不太明确的方法(这里不使用)https://gist.github.com/tjrobinson/0ad6c790e90d7a385eb1
//来自堆栈交换上的rajarameshvarma,此处:https://github.com/IdentityServer/IdentityServer3/issues/995
//启动代码取自IdentityServer3示例中的CustomUserService项目。
公共类ADUserService:UserServiceBase//UserServiceBase
{
静态类ADAttributes
{
公共静态字符串SamAccountName=“SamAccountName”;
公共静态字符串Mail=“Mail”;
公共静态字符串UserGroup=“UserGroup”;
公共静态字符串DisplayName=“DisplayName”;
公共静态字符串Department=“Department”;
公共静态字符串StreetAddress=“StreetAddress”;
公共静态字符串Phone=“电话号码”;
公共静态字符串State=“st”;
公共静态字符串City=“l”;
公共静态字符串Zip=“postalCode”;
公共静态字符串name=“sn”;
公共静态字符串Givenname=“Givenname”;
}
常量字符串ActiveDirectoryConnectionString=“CnnActiveDir”;
#区域设置与建设
//Func _ldapConnectionDelegate;//接收域并返回LDAP连接字符串的委托。
//默认ctor读取连接字符串
public ADUserService()//Func ldapConnectionDelegate)
{
//_ldapConnectionDelegate=ldapConnectionDelegate;
//调试(“调用了ADUserService”);
}
//..区域设置和建设
#端区
#区域通过声明进行身份验证
#区域验证外部-不支持
public System.Threading.Tasks.Task AuthenticateExternalAsync(IdentityServer3.Core.Models.ExternalIdentity外部用户,IdentityServer3.Core.Models.SigningMessage消息)
{
返回Task.FromResult(空);
}
#端区
公共任务AuthenticateLocalAsync(
字符串userDomainAndName,//有时称为“主题”
字符串密码,
签名信息(信息)
{
bool isUserValid=false;
if(string.IsNullOrEmpty(userDomainAndName)
||userDomainAndName.IndexOf(@“\”)<1)//应为:给定的某些域名后跟反斜杠
{
Log.Debug(“提供的用户名缺少域。身份验证被拒绝”);
return Task.FromResult(null);//失败!!
}
var split=userDomainAndName.ToLower().split('\\');//假定用户名的格式为domain\user
字符串域=拆分[0];
字符串用户名=拆分[1];
使用(PrincipalContext pc=new PrincipalContext(ContextType.Domain,Domain))
{
isUserValid=pc.Val
namespace Crb.Auth.AuthServer.Securing
{
    using System;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Threading.Tasks;
    using System.DirectoryServices;
    using System.Security.Claims;

    using System.DirectoryServices.AccountManagement;
    using IdentityServer3.Core;
    using IdentityServer3.Core.Services;
    using IdentityServer3.Core.Models;
    using IdentityServer3.Core.Extensions;
    using IdentityServer3.Core.Services.Default;

    using Serilog;

    // according to gist https://gist.github.com/rmbrunet/6c5c2ba2b8fb03fbc359
    // from rmbrunet on Stack Exchange here: https://github.com/IdentityServer/IdentityServer3/issues/1366

    // A slightly cleaner but less explicit approach (not used here) is in https://gist.github.com/tjrobinson/0ad6c790e90d7a385eb1
    // from rajarameshvarma on Stack Exchange here: https://github.com/IdentityServer/IdentityServer3/issues/995

    // Startup code is taken from the CustomUserService project in the IdentityServer3 Samples.

    public class ADUserService : UserServiceBase //UserServiceBase
    {
        static class ADAttributes
        {
            public static string SamAccountName = "samaccountname";
            public static string Mail = "mail";
            public static string UserGroup = "usergroup";
            public static string DisplayName = "displayname";
            public static string Department = "department";
            public static string StreetAddress = "streetAddress";
            public static string Phone = "telephoneNumber";
            public static string State = "st";
            public static string City = "l";
            public static string Zip = "postalCode";
            public static string Surname = "sn";
            public static string Givenname = "givenName";
        }

        const string ActiveDirectoryConnectionStringname = "CnnActiveDir";

        #region setup and construction
        //Func<string, string> _ldapConnectionDelegate; //Delegate that receives the domain and returns the LDAP connection string.

        // default ctor reads from connection string
        public ADUserService()//Func<string, string> ldapConnectionDelegate)
        {
            //_ldapConnectionDelegate = ldapConnectionDelegate;
            //Log.Debug("ADUserService called");
        }
        //.. region setup and construction
        #endregion

        #region authenticate with claims

        #region authenticate external - not supported
        public System.Threading.Tasks.Task<IdentityServer3.Core.Models.AuthenticateResult> AuthenticateExternalAsync(IdentityServer3.Core.Models.ExternalIdentity externalUser, IdentityServer3.Core.Models.SignInMessage message)
        {
            return Task.FromResult<AuthenticateResult>(null);
        }
        #endregion

        public Task<AuthenticateResult> AuthenticateLocalAsync(
            string userDomainAndName, // sometimes referred to as 'the subject'
            string password,
            SignInMessage message)
        {

            bool isUserValid = false;

            if (string.IsNullOrEmpty(userDomainAndName) 
                || userDomainAndName.IndexOf(@"\") < 1) // expected: some domain name given followed by a backslash
            {
                Log.Debug("Supplied username missing domain. Authentication denied.");
                return Task.FromResult<AuthenticateResult>(null); // Failed!! 
            }
            var split = userDomainAndName.ToLower().Split('\\'); //username assumed to be in the form domain\user
            string domain = split[0];
            string username = split[1];


            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
            {
                isUserValid = pc.ValidateCredentials(username, password);
            }

            if (!isUserValid)
            {
                Log.Debug("Authentication attempt failed for {0}", userDomainAndName);
                return Task.FromResult<AuthenticateResult>(null);
            }

            return Task.FromResult<AuthenticateResult>(
                new AuthenticateResult(subject: username.ToLower(), name: username));
        }

        #region pre-authenticate async - not supported
        public System.Threading.Tasks.Task<IdentityServer3.Core.Models.AuthenticateResult> PreAuthenticateAsync(IdentityServer3.Core.Models.SignInMessage message)
        {
            return Task.FromResult<AuthenticateResult>(null);
        }
        #endregion
        //..region authenticate
        #endregion

        #region profile

        public System.Threading.Tasks.Task<IEnumerable<System.Security.Claims.Claim>> GetProfileDataAsync(
            System.Security.Claims.ClaimsPrincipal principal,
            IEnumerable<string> requestedClaimTypes = null)
        {

            List<System.Security.Claims.Claim> claims = new List<Claim>(); //x null;


            string subject = principal.GetSubjectId();
            if ( ! string.IsNullOrEmpty(subject) )
                claims.Add(new Claim(Constants.ClaimTypes.Subject, subject)); // notice: idsrv3 short name convention as opposed to claims with full type

            SearchResult result = findUser(subject);
            if (result != null &&
                result.Properties.Contains(ADAttributes.Mail) &&
                result.Properties.Contains(ADAttributes.DisplayName))
            {
                claims.Add(new Claim(ClaimTypes.Email, (String)result.Properties[ADAttributes.Mail][0]));
                claims.Add(new Claim(ClaimTypes.Name, (String)result.Properties[ADAttributes.DisplayName][0]));

                if (result.Properties.Contains(ADAttributes.Surname))
                    claims.Add(new Claim(ClaimTypes.Surname, (String)result.Properties[ADAttributes.Surname][0]));

                if (result.Properties.Contains(ADAttributes.Givenname))
                    claims.Add(new Claim(ClaimTypes.GivenName, (String)result.Properties[ADAttributes.Givenname][0]));

                //Is there an address?
                if (result.Properties.Contains(ADAttributes.State)
                    && result.Properties.Contains(ADAttributes.StreetAddress)
                    && result.Properties.Contains(ADAttributes.City)
                    && result.Properties.Contains(ADAttributes.Zip))
                {

                    string state = (String)result.Properties[ADAttributes.State][0];
                    string street = (String)result.Properties[ADAttributes.StreetAddress][0];
                    string city = (String)result.Properties[ADAttributes.City][0];
                    string zip = (String)result.Properties[ADAttributes.Zip][0];

                    string address = string.Format("{0}, {1}, {2} {3}", street, city, state, zip);
                    claims.Add(new Claim(ClaimTypes.StreetAddress, address));
                }

                // Get roles from AD user groups
                var prince = principal.Identity as UserPrincipal;
                var groups = prince.GetGroups();
                foreach (var group in groups)
                    claims.Add(new Claim(ClaimTypes.Role, "dpn:" + group.DisplayName+",dtn:"+group.DistinguishedName ));

                claims = claims.Where(x => requestedClaimTypes.Contains(x.Type)).ToList();
            }

            return Task.FromResult(claims.AsEnumerable());
        }
        //.. region profile
        #endregion

        #region sign-out

        public System.Threading.Tasks.Task SignOutAsync(System.Security.Claims.ClaimsPrincipal subject)
        {
            return Task.FromResult(0);
        }
        //..region sign-out
        #endregion

        #region internals

        SearchResult findUser(string subject)
        {
            string[] a = subject.Split('\\');

            string domain = a[0];
            string username = a[1];

            string node = ConfigurationManager.ConnectionStrings[ActiveDirectoryConnectionStringname].ConnectionString;
                            //x _ldapConnectionDelegate(domain);


            using (DirectoryEntry searchRoot = new DirectoryEntry(node))
            {
                using (DirectorySearcher search = new DirectorySearcher(searchRoot))
                {

                    search.Filter = string.Format("(&(objectClass=user)(objectCategory=person)(SAMAccountName={0}))", username);
                    //search.PropertiesToLoad.Add( Constants.ADAttributes.SamAccountName );
                    search.PropertiesToLoad.Add(ADAttributes.Mail);
                    search.PropertiesToLoad.Add(ADAttributes.UserGroup);
                    search.PropertiesToLoad.Add(ADAttributes.DisplayName);
                    search.PropertiesToLoad.Add(ADAttributes.Surname);
                    search.PropertiesToLoad.Add(ADAttributes.Givenname);
                    search.PropertiesToLoad.Add(ADAttributes.Department);
                    search.PropertiesToLoad.Add(ADAttributes.StreetAddress);
                    search.PropertiesToLoad.Add(ADAttributes.Phone);
                    search.PropertiesToLoad.Add(ADAttributes.State);
                    search.PropertiesToLoad.Add(ADAttributes.City);
                    search.PropertiesToLoad.Add(ADAttributes.Zip);

                    return search.FindOne();
                }
            }
        }

        public System.Threading.Tasks.Task<bool> IsActiveAsync(System.Security.Claims.ClaimsPrincipal principal)
        {
            string subject = principal.GetSubjectId(); // this should return the "distinguished name" (sub.maindomain/username)
            SearchResult result = findUser(subject);
            return Task.FromResult(result != null);
        }
        //.. region internals
        #endregion
    }
}