/// <summary>
        /// 지정된 토큰 제거
        /// </summary>
        /// <param name="sRefreshToken"></param>
        /// <returns></returns>
        public async Task <TokenRevocationResponse> RevocationTokenAsync(string sRefreshToken)
        {
            //엑세스 토큰도 제거가 가능하지만
            //이 시나리오에서는 리플레시 토큰만 제거하면 된다.
            TokenRevocationResponse trRequestToken
                = await hcAuthClient
                  .RevokeTokenAsync(new TokenRevocationRequest
            {
                Address      = this.sIdentityServer4_Url + "connect/revocation",
                ClientId     = this.ClientId,
                ClientSecret = this.ClientSecret,

                Token         = sRefreshToken,
                TokenTypeHint = "refresh_token"
            });

            GlobalSign.LogAdd_DB(
                2
                , ModelDB.UserSignLogType.RevocationToken
                , 0
                , string.Format("RevocationTokenAsync = {0} : "
                                , trRequestToken.HttpErrorReason));

            return(trRequestToken);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Revoke token call
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="refresh_token"></param>
        /// <returns></returns>
        private async System.Threading.Tasks.Task performRevokeToken(string access_token, string refresh_token)
        {
            output("Performing Revoke tokens.");

            var revokeClient = new TokenRevocationClient(revokeEndpoint, clientID, clientSecret);

            //Revoke access token
            TokenRevocationResponse revokeAccessTokenResponse = await revokeClient.RevokeAccessTokenAsync(access_token);

            var revokeAccessTokenStatus = revokeAccessTokenResponse.HttpStatusCode;

            if (revokeAccessTokenStatus == HttpStatusCode.OK)
            {
                //We are removing all sessions and querystring here even if we get error on revoke.
                //In your code, you can choose to handle the errors and then delete sessions and querystring
                //Session.Clear();
                //Session.Abandon();
                dictionary.Clear();
                if (Request.Url.Query == "")
                {
                    Response.Redirect(Request.RawUrl);
                }
                else
                {
                    Response.Redirect(Request.RawUrl.Replace(Request.Url.Query, ""));
                }
            }
            output("Token revoked.");
        }
Exemplo n.º 3
0
 /// <summary>
 /// Creates the revocation endpoint response and processes the revocation request.
 /// </summary>
 /// <param name="validationResult">The userinfo request validation result.</param>
 /// <returns></returns>
 public virtual async Task <TokenRevocationResponse> ProcessAsync(TokenRevocationRequestValidationResult validationResult)
 {
     if (validationResult.TokenTypeHint == Constants.TokenTypeHints.Subject)
     {
         var response = new TokenRevocationResponse
         {
             Success   = false,
             TokenType = validationResult.TokenTypeHint
         };
         var client = validationResult.Client as ClientExtra;
         if (client.AllowGlobalSubjectRevocation)
         {
             Logger.LogInformation($"TokenRevocation: client={client.ClientId},subject={validationResult.Token}");
             response.Success = await RevokeSubjectAsync(validationResult);
         }
         else
         {
             Logger.LogError($"client={client.ClientId},AllowGlobalSubjectRevocation={client.AllowGlobalSubjectRevocation}");
         }
         return(response);
     }
     else
     {
         return(await _idsTokenRevocationResponseGenerator.ProcessAsync(validationResult));
     }
 }
Exemplo n.º 4
0
        private static async Task <TokenRevocationResponse> ForceTokenTimeout(TokenRevocationRequest request)
        {
            TokenRevocationResponse response = null;

            if (request != null)
            {
                response = await new HttpClient().RevokeTokenAsync(request);
            }

            return(response);
        }
Exemplo n.º 5
0
        private async void btnOidcSignoutCode_Click(object sender, EventArgs e)
        {
            var disco  = DiscoveryClient.GetAsync("http://localhost:5001").Result;
            var client = new TokenRevocationClient(disco.RevocationEndpoint, txtoidcClientIdCode.Text, "secret");
            TokenRevocationResponse response = await client.RevokeAccessTokenAsync(txtOidcAccessTokenCode.Text);

            if (!string.IsNullOrEmpty(response.Raw))
            {
                txtOidcSignoutCode.Text = response.Raw;
            }
        }
Exemplo n.º 6
0
        [Authorize]//OAuth2 인증 설정
        public ActionResult <string> SignOut(
            [FromForm] string sRefreshToken)
        {
            ApiResultReady rrResult = new ApiResultReady(this);

            //API 호출 시간
            DateTime dtNow = DateTime.Now;

            //인증 정보에서 유저 정보 추출
            var        identity = (ClaimsIdentity)User.Identity;
            ClaimModel cm       = new ClaimModel(identity.Claims);

            //사인아웃 시도 기록
            GlobalSign.LogAdd_DB(
                1
                , ModelDB.UserSignLogType.SignOut
                , cm.id_int
                , string.Format("SignOut 시도 : {0}", cm.email));


            using (SpaNetCoreFoundationContext db1 = new SpaNetCoreFoundationContext())
            {
                //기존 로그인한 유저 검색
                UserSignIn[] arrSL
                    = db1.UserSignIn
                      .Where(m => m.idUser == cm.id_int)
                      .ToArray();

                //기존 로그인한 유저 정보 제거
                db1.UserSignIn.RemoveRange(arrSL);
                //db 적용
                db1.SaveChanges();
            }


            //리플레시 토큰 제거
            if ((null != sRefreshToken) &&
                (string.Empty != sRefreshToken))
            {
                TokenRevocationResponse trr
                    = GlobalStatic.TokenProc
                      .RevocationTokenAsync(sRefreshToken)
                      .Result;
            }

            //로컬 인증 쿠키 삭제 요청
            HttpContext.SignOutAsync();

            //임시로 아이디를 넘긴다.
            return(rrResult.ToResult());
        }
Exemplo n.º 7
0
        public ActionResult <SignInResultModel> SignOut(
            [FromForm] string sRefreshToken)
        {
            ApiResultReadyModel armResult = new ApiResultReadyModel(this);
            ApiResultBaseModel  arbm      = new ApiResultBaseModel();

            //사인아웃에 필요한 작업을 한다.
            //리플레시 토큰 제거
            TokenRevocationResponse trr = RevocationTokenAsync(sRefreshToken).Result;

            //로컬 인증 쿠키 삭제 요청
            HttpContext.SignOutAsync();
            //임시로 아이디를 넘긴다.
            return(armResult.ToResult(arbm));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Revoke Reference|Refresh token
        /// </summary>
        /// <param name="token">Reference|Refresh Token</param>
        /// <returns>TokenRevocationResponse</returns>
        public async Task <TokenRevocationResponse> RevokeTokenAsync(string token)
        {
            // Use Cached Discovery Document
            this.discoResponse = await this.discoverCachedDocumentAsync();

            var httpClient = this.httpClientFactory.CreateClient(HttpClientNameFactory.AuthHttpClient);
            TokenRevocationResponse revokeResposne = await httpClient.RevokeTokenAsync(new TokenRevocationRequest
            {
                Address      = this.discoResponse.RevocationEndpoint,
                ClientId     = this.clientId,
                ClientSecret = this.secret,
                Token        = token
            });

            return(revokeResposne);
        }
        public async Task missing_token_should_return_error()
        {
            var data = new Dictionary <string, string>
            {
                { "client_id", client_id },
                { "client_secret", client_secret },
            };

            var response = await _mockPipeline.Client.PostAsync(MockIdSvrUiPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));

            response.StatusCode.Should().Be(HttpStatusCode.BadRequest);

            var result = new TokenRevocationResponse(await response.Content.ReadAsStringAsync());

            result.IsError.Should().BeTrue();
            result.Error.Should().Be("invalid_request");
        }
Exemplo n.º 10
0
        /// <summary>
        /// Revoke Reference|Refresh token
        /// </summary>
        /// <param name="token">Reference|Refresh Token</param>
        /// <returns>TokenRevocationResponse</returns>
        public async Task <TokenRevocationResponse> RevokeTokenAsync(string token)
        {
            if (this.discoResponse == null)
            {
                this.discoResponse = await this.discoverDocumentAsync();
            }

            var httpClient = this.httpClientFactory.CreateClient("AuthHttpClient");
            TokenRevocationResponse revokeResposne = await httpClient.RevokeTokenAsync(new TokenRevocationRequest
            {
                Address      = this.discoResponse.RevocationEndpoint,
                ClientId     = CLIENTID,
                ClientSecret = SECRETKEY,
                Token        = token
            });

            return(revokeResposne);
        }
Exemplo n.º 11
0
        public async Task <ActionResult> RevokeRefreshToken()
        {
            var refreshToken = (User as ClaimsPrincipal).FindFirst("refresh_token").Value;

            //Revoke Refresh token call
            var revokeClient = new TokenRevocationClient(AppController.revocationEndpoint, clientid, clientsecret);

            //Revoke refresh token
            TokenRevocationResponse revokeAccessTokenResponse = await revokeClient.RevokeAccessTokenAsync(refreshToken);

            if (revokeAccessTokenResponse.HttpStatusCode == HttpStatusCode.OK)
            {
                Session.Abandon();
                Request.GetOwinContext().Authentication.SignOut();
            }
            //return RedirectToAction("Index");
            return(RedirectToAction("Index"));
        }
Exemplo n.º 12
0
        /// <summary>
        /// 지정된 토큰 제거
        /// </summary>
        /// <param name="sRefreshToken"></param>
        /// <returns></returns>
        private async Task <TokenRevocationResponse> RevocationTokenAsync(string sRefreshToken)
        {
            //엑세스 토큰도 제거가 가능하지만
            //이 시나리오에서는 리플레시 토큰만 제거하면 된다.
            TokenRevocationResponse trRequestToken
                = await hcAuthClient
                  .RevokeTokenAsync(new TokenRevocationRequest
            {
                Address      = this.sIdentityServer4_Url + "connect/revocation",
                ClientId     = "resourceownerclient",
                ClientSecret = "dataEventRecordsSecret",

                Token         = sRefreshToken,
                TokenTypeHint = "refresh_token"
            });

            return(trRequestToken);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Creates the revocation endpoint response and processes the revocation request.
        /// </summary>
        /// <param name="validationResult">The userinfo request validation result.</param>
        /// <returns></returns>
        public virtual async Task <TokenRevocationResponse> ProcessAsync(TokenRevocationRequestValidationResult validationResult)
        {
            var response = new TokenRevocationResponse
            {
                Success   = false,
                TokenType = validationResult.TokenTypeHint
            };

            // revoke tokens
            if (validationResult.TokenTypeHint == TokenTypeHints.AccessToken)
            {
                Logger.LogTrace("Hint was for access token");
                response.Success = await RevokeAccessTokenAsync(validationResult);
            }
            else if (validationResult.TokenTypeHint == TokenTypeHints.RefreshToken)
            {
                Logger.LogTrace("Hint was for refresh token");
                response.Success = await RevokeRefreshTokenAsync(validationResult);
            }
            else if (validationResult.TokenTypeHint == IdentityServer4Extras.Constants.TokenTypeHints.Subject)
            {
                Logger.LogTrace("Hint was for subject");
                response.Success = await RevokeSubjectAsync(validationResult);
            }
            else
            {
                Logger.LogTrace("No hint for token type");

                response.Success = await RevokeAccessTokenAsync(validationResult);

                if (!response.Success)
                {
                    response.Success = await RevokeRefreshTokenAsync(validationResult);

                    response.TokenType = TokenTypeHints.RefreshToken;
                }
                else
                {
                    response.TokenType = TokenTypeHints.AccessToken;
                }
            }

            return(response);
        }
        public async Task <ActionResult <TokenRevocationResponse> > RevokeToken([FromBody] TokenRequestDTO tokenRequest)
        {
            try
            {
                TokenRevocationResponse result = await _userService.RevokeToken(tokenRequest)
                                                 .ConfigureAwait(false);

                if (!result.IsError)
                {
                    return(Ok());
                }
                return(Conflict(result.Json));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "POST:/revoke");
                return(StatusCode(StatusCodes.Status500InternalServerError));
            }
        }
Exemplo n.º 15
0
    /// <summary>
    /// Creates the revocation endpoint response and processes the revocation request.
    /// </summary>
    /// <param name="validationResult">The userinfo request validation result.</param>
    /// <returns></returns>
    public virtual async Task <TokenRevocationResponse> ProcessAsync(TokenRevocationRequestValidationResult validationResult)
    {
        using var activity = Tracing.BasicActivitySource.StartActivity("TokenRevocationResponseGenerator.Process");

        var response = new TokenRevocationResponse
        {
            Success   = false,
            TokenType = validationResult.TokenTypeHint
        };

        // revoke tokens
        if (validationResult.TokenTypeHint == Constants.TokenTypeHints.AccessToken)
        {
            Logger.LogTrace("Hint was for access token");
            response.Success = await RevokeAccessTokenAsync(validationResult);
        }
        else if (validationResult.TokenTypeHint == Constants.TokenTypeHints.RefreshToken)
        {
            Logger.LogTrace("Hint was for refresh token");
            response.Success = await RevokeRefreshTokenAsync(validationResult);
        }
        else
        {
            Logger.LogTrace("No hint for token type");

            response.Success = await RevokeAccessTokenAsync(validationResult);

            if (!response.Success)
            {
                response.Success = await RevokeRefreshTokenAsync(validationResult);

                response.TokenType = Constants.TokenTypeHints.RefreshToken;
            }
            else
            {
                response.TokenType = Constants.TokenTypeHints.AccessToken;
            }
        }

        return(response);
    }
Exemplo n.º 16
0
        /// <summary>
        /// get token response
        /// </summary>
        /// <param name="request">token reqeust</param>
        /// <param name="requestType">requestType</param>
        /// <returns>AngelTokenResponse</returns>
        public static async Task <AngelTokenResponse> GetTokenResponse(AngelTokenRequest request, TokenRequestType requestType)
        {
            if (request == null)
            {
                return(null);
            }

            AngelTokenResponse      angelResposne      = null;
            TokenResponse           response           = null;
            TokenRevocationResponse revocationResponse = null;

            switch (requestType)
            {
            case TokenRequestType.client_credential:
                response = await GetClientCredentialToken(request.Map());

                angelResposne = response?.Map();
                break;

            case TokenRequestType.resource_password:
                response = await GetResourcePasswordToken(request.MapPasswordRequest());

                angelResposne = response?.Map();
                break;

            case TokenRequestType.revocation:
                revocationResponse = await ForceTokenTimeout(request.MapRevocationRequest());

                angelResposne = response?.Map();
                break;

            case TokenRequestType.refresh:
                response = await ReferenceToken(request.MapRefRequest());

                angelResposne = response?.Map();
                break;
            }

            return(angelResposne);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Implements the interface method by invoking the related delegate method.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task SigningOut(CookieSigningOutContext context)
        {
            if (this.AutomaticTokenManagementOptions.RevokeRefreshTokenOnSignout == false)
            {
                return;
            }

            AuthenticateResult result = await context.HttpContext.AuthenticateAsync();

            if (!result.Succeeded)
            {
                this.Logger.LogDebug("Can't find cookie for default scheme. Might have been deleted already.");
                return;
            }

            IEnumerable <AuthenticationToken> tokens = result.Properties.GetTokens();

            if (tokens == null || !tokens.Any())
            {
                this.Logger.LogDebug("No tokens found in cookie properties. SaveTokens must be enabled for automatic token revocation.");
                return;
            }

            AuthenticationToken refreshToken = tokens.SingleOrDefault(t => t.Name == OpenIdConnectParameterNames.RefreshToken);

            if (refreshToken == null)
            {
                this.Logger.LogWarning("No refresh token found in cookie properties. A refresh token must be requested and SaveTokens must be enabled.");
                return;
            }

            TokenRevocationResponse response = await this.TokenEndpointService.RevokeTokenAsync(refreshToken.Value);

            if (response.IsError)
            {
                this.Logger.LogWarning("Error revoking token: {error}", response.Error);
                return;
            }
        }
Exemplo n.º 18
0
        public async Task invalid_token_type_hint_should_return_error()
        {
            var tokens = await GetTokensAsync();

            (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();

            var data = new Dictionary <string, string>
            {
                { "client_id", client_id },
                { "client_secret", client_secret },
                { "token", tokens.AccessToken },
                { "token_type_hint", "not_valid" },
            };

            var response = await _mockPipeline.Client.PostAsync(MockIdSvrUiPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));

            response.StatusCode.Should().Be(HttpStatusCode.BadRequest);

            var result = new TokenRevocationResponse(await response.Content.ReadAsStringAsync());

            result.IsError.Should().BeTrue();
            result.Error.Should().Be("unsupported_token_type");
        }
Exemplo n.º 19
0
        protected override void ExecuteRequest(HttpContext context)
        {
            (bool isOk, User user) = CheckClaimsForUser(Request, context, _userRepository);
            if (!isOk || user == null)
            {
                return;
            }

            string fullAddress = $"{HTTP}{address}:{port}";
            var    client      = new HttpClient();
            DiscoveryDocumentResponse discoDoc = client.GetDiscoveryDocumentAsync(fullAddress).GetAwaiter().GetResult();
            TokenRevocationRequest    tokenRevocationRequest = new TokenRevocationRequest
            {
                Address       = discoDoc.RevocationEndpoint,
                ClientId      = user.Login,
                ClientSecret  = user.PasswordHash,
                Token         = Request.AccessToken,
                TokenTypeHint = "access_token"
            };
            TokenRevocationResponse tokenRevocationResponse = client.RevokeTokenAsync(tokenRevocationRequest).GetAwaiter().GetResult();

            context.Response.StatusCode = (int)tokenRevocationResponse.HttpStatusCode;
        }
        [Authorize]//OAuth2 인증 설정
        public ActionResult <string> SignOut(
            [FromForm] int nID
            , [FromForm] string sRefreshToken)
        {
            ApiResultReady rrResult = new ApiResultReady(this);

            //사인아웃에 필요한 작업을 한다.
            //사용자
            GlobalStatic.SignInList.Delete(nID, sRefreshToken);

            //리플레시 토큰 제거
            if ((null != sRefreshToken) &&
                (string.Empty != sRefreshToken))
            {
                TokenRevocationResponse trr = GlobalStatic.TokenProc.RevocationTokenAsync(sRefreshToken).Result;
            }

            //로컬 인증 쿠키 삭제 요청
            HttpContext.SignOutAsync();

            //임시로 아이디를 넘긴다.
            return(rrResult.ToResult());
        }
Exemplo n.º 21
0
        public ActionResult <SignInResultModel> SignIn(
            [FromForm] string sEmail
            , [FromForm] string sPW)
        {
            //결과용
            ApiResultReady rrResult = new ApiResultReady(this);
            //로그인 처리용 모델
            SignInResultModel rmResult = new SignInResultModel();

            rrResult.ResultObject = rmResult;

            //API 호출 시간
            DateTime dtNow = DateTime.Now;

            //사인인 시도 기록
            GlobalSign.LogAdd_DB(
                1
                , ModelDB.UserSignLogType.SignIn
                , 0
                , string.Format("SignIn 시도 - {0}, {1}", sEmail, sPW));


            //검색된 유저
            User findUser = null;

            using (SpaNetCoreFoundationContext db1 = new SpaNetCoreFoundationContext())
            {
                //유저 검색
                findUser
                    = db1.User
                      .FirstOrDefault(m =>
                                      m.SignEmail == sEmail &&
                                      m.Password == sPW);
            }


            if (findUser != null)
            {
                //토큰 요청
                TokenResponse tr = GlobalStatic.TokenProc.RequestTokenAsync(sEmail, sPW).Result;

                if (true == tr.IsError)
                {//에러가 있다.
                    rrResult.InfoCode = "1";
                    rrResult.Message  = "아이디나 비밀번호가 틀렸습니다.";
                }
                else
                {//에러가 없다.
                    using (SpaNetCoreFoundationContext db1 = new SpaNetCoreFoundationContext())
                    {
                        //기존 로그인한 유저 검색
                        UserSignIn[] arrSL
                            = db1.UserSignIn
                              .Where(m => m.idUser == findUser.idUser)
                              .ToArray();

                        //기존 로그인 토큰 제거
                        foreach (UserSignIn itemUSI in arrSL)
                        {
                            //리플레시 토큰 제거
                            if ((null != itemUSI.RefreshToken) &&
                                (string.Empty != itemUSI.RefreshToken))
                            {
                                TokenRevocationResponse trr
                                    = GlobalStatic.TokenProc
                                      .RevocationTokenAsync(itemUSI.RefreshToken)
                                      .Result;
                            }
                        }//end foreach itemUSI

                        //기존 로그인한 유저 정보 제거
                        db1.UserSignIn.RemoveRange(arrSL);
                        //db 적용
                        db1.SaveChanges();

                        //사인인 한 유저의 정보
                        UserInfo findUI
                            = db1.UserInfo
                              .Where(m => m.idUser == findUser.idUser)
                              .FirstOrDefault();

                        //로그인 되어있는 유저정보 저장
                        UserSignIn slItem = new UserSignIn();
                        slItem.idUser       = findUser.idUser;
                        slItem.RefreshToken = tr.RefreshToken;
                        slItem.SignInDate   = dtNow;
                        slItem.RefreshDate  = dtNow;

                        //기존 로그인한 유저 정보 제거
                        db1.UserSignIn.Add(slItem);
                        //db 적용
                        db1.SaveChanges();

                        //로그인한 유저에게 전달할 정보
                        rmResult.idUser   = findUser.idUser;
                        rmResult.Email    = findUser.SignEmail;
                        rmResult.ViewName = findUI.ViewName;

                        rmResult.MgtClass = findUI.MgtClass;

                        rmResult.access_token  = tr.AccessToken;
                        rmResult.refresh_token = tr.RefreshToken;

                        //성공 로그
                        //사인인 성공 기록
                        GlobalSign.LogAdd_DB(
                            1
                            , ModelDB.UserSignLogType.SignIn
                            , findUser.idUser
                            , string.Format("SignIn 성공 - {0}", sEmail));
                    }//end using db1
                }
            }
            else
            {
                rrResult.InfoCode = "1";
                rrResult.Message  = "아이디나 비밀번호가 틀렸습니다.";
            }

            return(rrResult.ToResult(rmResult));
        }