1. 程式人生 > >abp 使用OAuthBearerAuthenticationOptions物件裡屬性AccessTokenFormat對應的Protect方法報空指標異常解決方法

abp 使用OAuthBearerAuthenticationOptions物件裡屬性AccessTokenFormat對應的Protect方法報空指標異常解決方法

由於要自己要在自定義的service類定義一個和登陸相關的介面,所有需要模仿api下面的AccountController登陸並返回ticket,但是對應的AccessTokenFormat老是報空指標異常,下面說說我做的步驟以及解決方法。

 

abp原有Api解決方案下面的使用程式碼如下面主要兩個程式碼段

這裡初始化OAuthBearerAuthenticationOptions

 public class AccountController : AbpApiController
    {
        public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }


        static AccountController()
        {
            OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        }

這裡登陸後利用OAuthBearerAuthenticationOptions返回對應的ticket

HttpPost]
        public async Task<AjaxResponse> Authenticate(LoginModel loginModel)
        {
            CheckModelState();

            var loginResult = await GetLoginResultAsync(
                loginModel.UsernameOrEmailAddress,
                loginModel.Password,
                loginModel.TenancyName
                );

            var ticket = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties());

            var currentUtc = new SystemClock().UtcNow;
            ticket.Properties.IssuedUtc = currentUtc;
            ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));

            return new AjaxResponse(OAuthBearerOptions.AccessTokenFormat.Protect(ticket));
        }

然後下面是我模仿的主要程式碼段一

public class TripAppService : ApplicationService, ITripAppService
    {
        public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }



        static TripAppService()
        {
            OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        }

下面是程式碼段二,某個方法裡面的一段程式碼

//使用者登入
                        var loginResult = await _logInManager.LoginByMobileAsync(phoneNumber, tenancyName);
                        if (loginResult.Result == AbpLoginResultType.Success)
                        {
                            var token = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties());
                            var currentUtc = new SystemClock().UtcNow;
                            token.Properties.IssuedUtc = currentUtc;
                            token.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
                            output.Token = OAuthBearerOptions.AccessTokenFormat.Protect(token);
                        }

但是一執行就會報錯,找了半天也沒找到原因,最後好不容易找到原因,原來是沒有配置,配置是在web網站下面的appstart資料夾下的startup類裡面配置一下該物件,如以下程式碼

public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseAbp();

            app.UseOAuthBearerAuthentication(AccountController.OAuthBearerOptions);

            app.UseOAuthBearerAuthentication(Trips.TripAppService.OAuthBearerOptions);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                // evaluate for Persistent cookies (IsPermanent == true). Defaults to 14 days when not set.
                ExpireTimeSpan = new TimeSpan(int.Parse(ConfigurationManager.AppSettings["AuthSession.ExpireTimeInDays.WhenPersistent"] ?? "14"), 0, 0, 0),
                SlidingExpiration = bool.Parse(ConfigurationManager.AppSettings["AuthSession.SlidingExpirationEnabled"] ?? bool.FalseString)
            });

            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            app.MapSignalR();
        }
    }

重點:這個方法雖然可以最後生成ticket,但是會導致另外的錯誤,會導致介面不能訪問報Sequence contains more than one element專案裡面不能有兩個該配置,哭死了,進死衚衕了,最後只能把方法寫到accountcontroller裡面了