ASP. NET 웹 Api 보안
16668 단어 asp.net
웹 Api 에서 Https 강제 사용
우 리 는 IIS 단계 에서 웹 Api 전 체 를 설정 하여 Https 를 강제 적 으로 사용 할 수 있 지만, 어떤 경우 에는 하나의 action 에 대해 Https 를 강제 적 으로 사용 해 야 할 수도 있 고, 다른 방법 은 http 를 사용 할 수도 있 습 니 다.
이 를 위해 웹 Api 의 filers - filter (필터) 를 사용 하 는 주요 역할 은 우리 가 방법 을 실행 하기 전에 코드 를 실행 할 수 있 는 것 입 니 다.접촉 한 적 이 없 으 면 다음 그림 을 통 해 간단하게 이해 하고 대신 이 건 너 뛸 수 있 습 니 다.
우리 가 새로 만 든 filter 는 안전 한 지 여 부 를 검사 하 는 데 사 용 될 것 입 니 다. 안전 하지 않 으 면 filter 는 요청 을 중지 하고 해당 되 는 것 을 되 돌려 줍 니 다. 요청 은 https 여야 합 니 다.
구체 적 인 방법: Authorization FilterAttribute 에서 filter 를 만 들 고 OnAuthorization 을 다시 써 서 우리 의 수 요 를 실현 합 니 다.
웹 사이트 루트 디 렉 터 리 에 "Filters" 폴 더 를 만 듭 니 다. "ForceHttpsAttribute" 는 "System. Web. Http. Filters. Authorization FilterAttribute" 에서 계승 합 니 다. 아래 코드 는 다음 과 같 습 니 다.
public class ForceHttpsAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var request = actionContext.Request;
if (request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
var html = "<p>Https is required</p>";
if (request.Method.Method == "GET")
{
actionContext.Response = request.CreateResponse(HttpStatusCode.Found);
actionContext.Response.Content = new StringContent(html, Encoding.UTF8, "text/html");
UriBuilder httpsNewUri = new UriBuilder(request.RequestUri);
httpsNewUri.Scheme = Uri.UriSchemeHttps;
httpsNewUri.Port = 443;//HTTPS(securely transferring web pages) , 443/tcp 443/udp;
actionContext.Response.Headers.Location = httpsNewUri.Uri;
}
else
{
actionContext.Response = request.CreateResponse(HttpStatusCode.NotFound);
actionContext.Response.Content = new StringContent(html, Encoding.UTF8, "text/html");
}
}
}
}
위의 코드 에서 저 희 는 actionContext 매개 변 수 를 통 해 request 와 response 대상 을 받 았 습 니 다. 저 희 는 클 라 이언 트 의 요청 을 판단 합 니 다. https 가 아니라면 클 라 이언 트 에 직접 응답 하려 면 https 를 사용 해 야 합 니 다.
여기 서 요청 이 Get 인지 다른 (Post, Delete, Put) 인지 구분 해 야 합 니 다. Http 를 사용 한 Get 요청 으로 자원 에 접근 하 는 경우 https 를 사용 하여 연결 을 만 들 고 Header 에 응답 하 는 Location 에 추가 할 것 입 니 다.이렇게 하면 클 라 이언 트 가 자동 으로 https 를 사용 하여 Get 요청 을 보 냅 니 다.
Get 요청 이 아 닌 경우 404 를 직접 되 돌려 주 고 클 라 이언 트 에 게 https 로 요청 해 야 한다 고 알려 줍 니 다.
만약 우리 가 전체 항목 에서 사용 하려 고 한다 면, "WebAPIConfig" 클래스 에서 다음 과 같은 설정 을 하 십시오.
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ForceHttpsAttribute());
}
만약 에 우리 가 상대 적 으로 구체 적 인 Controller 나 Action 설정 을 할 때 다음 과 같은 설정 을 할 수 있 습 니 다.
// Controller Https
[Learning.Web.Filters.ForceHttps()]
public class CoursesController : BaseApiController
{
// Https
[Learning.Web.Filters.ForceHttps()]
public HttpResponseMessage Post([FromBody] CourseModel courseModel)
{
}
}
Basic Authentication 을 사용 하여 사용 자 를 검증 합 니 다.
지금까지 저희 가 제공 한 모든 Api 는 공개 되 어 있 으 며 누구나 방문 할 수 있 습 니 다.그러나 정말 장면 에서 바람 직 하지 않다. 일부 데이터 에 대해 인증 을 통과 한 사용자 만 방문 할 수 있다. 우 리 는 여기 서 이 점 을 잘 설명 할 수 있다.
1. 클 라 이언 트 가 Get 요청 을 "http:// {your port} / api / students / {userName}" 로 보 낼 때. 예 를 들 어 상기 URI 를 통 해 userNme 를 "Taiseer Joudeh" 로 방문 합 니 다.의 정 보 를 제공 할 때 저 희 는 클 라 이언 트 에 게 Taiseer Joudeh 에 해당 하 는 사용자 이름과 비밀 번 호 를 제공 하도록 해 야 합 니 다. 검증 정 보 를 제공 하지 않 은 사용자 에 게 저 희 는 방문 하지 못 하 게 해 야 합 니 다. 왜냐하면 학생 정보 에는 중요 한 개인 정보 (email, birthday 등) 가 포함 되 어 있 기 때 문 입 니 다.
2. 클 라 이언 트 가 "http:// {your port} / api / courses / 2 / students / {userName}" 에 게 Post 요청 을 보 냈 을 때 이것 은 학생 들 에 게 수강 신청 을 하 는 것 을 의미 합 니 다. 여기 서 검증 을 하지 않 으 면 모든 사람 이 어떤 학생 에 게 마음대로 수강 신청 을 할 수 있다 면 혼 란 스 럽 지 않 겠 습 니까?
위의 장면 에 대해 저 희 는 Basic Authentication 을 사용 하여 인증 을 합 니 다. 주요 사 고 는 filter 를 사용 하여 헤더 부분 에서 신분 정 보 를 얻 고 인증 유형 이 'basic' 인지 확인 한 다음 에 내용 을 검증 하고 정확 하면 놓 습 니 다. 그렇지 않 으 면 401 (Unauthorized) 상태 코드 로 돌아 갑 니 다.
위 코드 전에 basic authentication 을 설명 하 십시오.
basic authentication 이란 무엇 입 니까?
이 는 Http 요청 을 본 격 적 으로 처리 하기 전에 요청 자의 신분 을 검증 하 는 것 을 의미 합 니 다. 이 는 서버 가 DoS 공격 (Denial of service attacks) 을 받 는 것 을 방지 할 수 있 습 니 다. 원 리 는 클 라 이언 트 가 Http 요청 을 보 낼 때 Header 부분 에 Base 64 인 코딩 을 기반 으로 한 사용자 이름과 비밀 번 호 를 제공 하 는 것 입 니 다. 'username: password', 메시지 수신 자 (서버) 입 니 다.검증 을 진행 하고 통과 후 요청 을 계속 처리 합 니 다.
사용자 이름과 비밀 번 호 는 base 64 인 코딩 만 적용 되 기 때문에 안전성 을 확보 하기 위해 basic authentication 은 보통 SSL 연결 (https) 을 기반 으로 합 니 다.
우리 api 에서 사용 하기 위해 서 "Learning AuthorizeAttribute" 를 만 들 고 System. Web. Http. Filters. AuthorizationFilterAttribute 에서 계승 합 니 다.
public class LearningAuthorizeAttribute : AuthorizationFilterAttribute
{
[Inject]
public LearningRepository TheRepository { get; set; }
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//forms authentication Case that user is authenticated using forms authentication
//so no need to check header for basic authentication.
if (Thread.CurrentPrincipal.Identity.IsAuthenticated)
{
return;
}
var authHeader = actionContext.Request.Headers.Authorization;
if (authHeader != null)
{
if (authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) &&
!String.IsNullOrWhiteSpace(authHeader.Parameter))
{
var credArray = GetCredentials(authHeader);
var userName = credArray[0];
var password = credArray[1];
if (IsResourceOwner(userName, actionContext))
{
//You can use Websecurity or asp.net memebrship provider to login, for
//for he sake of keeping example simple, we used out own login functionality
if (TheRepository.LoginStudent(userName, password))
{
var currentPrincipal = new GenericPrincipal(new GenericIdentity(userName), null);
Thread.CurrentPrincipal = currentPrincipal;
return;
}
}
}
}
HandleUnauthorizedRequest(actionContext);
}
private string[] GetCredentials(System.Net.Http.Headers.AuthenticationHeaderValue authHeader)
{
//Base 64 encoded string
var rawCred = authHeader.Parameter;
var encoding = Encoding.GetEncoding("iso-8859-1");
var cred = encoding.GetString(Convert.FromBase64String(rawCred));
var credArray = cred.Split(':');
return credArray;
}
private bool IsResourceOwner(string userName, System.Web.Http.Controllers.HttpActionContext actionContext)
{
var routeData = actionContext.Request.GetRouteData();
var resourceUserName = routeData.Values["userName"] as string;
if (resourceUserName == userName)
{
return true;
}
return false;
}
private void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
actionContext.Response.Headers.Add("WWW-Authenticate",
"Basic Scheme='eLearning' location='http://localhost:8323/account/login'");
}
}
"OnAuthorization" 을 다시 써 서 다음 과 같은 기능 을 실현 합 니 다.
1. Header 요청 에서 검사 데이터 가 져 오기
2. 인증 정보 유형 을 "basic" 로 판단 하고 base 64 인 코딩 포함
3. base 64 인 코딩 을 string 으로 바 꾸 고 사용자 이름과 비밀 번 호 를 추출 합 니 다.
4. 제 공 된 인증 정보 가 방문 한 자원 정보 와 같 는 지 확인 합 니 다 (학생 의 자세 한 정 보 는 그 가 직접 방문 할 수 있 습 니 다)
5. 데이터베이스 에 가서 사용자 이름과 비밀 번 호 를 확인 합 니 다.
6. 검증 이 통과 되면 Thread 의 Current Principal 을 설정 하여 다음 요청 이 모두 검증 을 통과 하도록 합 니 다.
7. 검증 이 통과 되 지 않 았 습 니 다. 401 (Unauthorized) 을 되 돌려 주 고 WWW - Authenticate 응답 헤드 를 추가 합 니 다. 이 요청 에 따라 클 라 이언 트 는 해당 하 는 인증 정 보 를 추가 할 수 있 습 니 다.
코드 에서 이 루어 지면 간단 합 니 다. 위의 Attribute 두 개 는 끝 입 니 다.
public class StudentsController : BaseApiController
{
[LearningAuthorizeAttribute]
public HttpResponseMessage Get(string userName)
{
}
}
public class EnrollmentsController : BaseApiController
{
[LearningAuthorizeAttribute]
public HttpResponseMessage Post(int courseId, [FromUri]string userName, [FromBody]Enrollment enrollment)
{
}
}
테스트 성과
테스트 도 구 를 사용 하여 다음 요청 을 보 냅 니 다:
인증 을 제공 하지 않 았 기 때문에 다음 과 같은 응답 을 받 았 습 니 다.
취소:
데이터베이스 에서 해당 하 는 사용자 이름과 비밀 번 호 를 찾 아 입력 하면 다음 과 같은 결 과 를 얻 을 수 있 습 니 다.
총결산
Base Authentication 은 안전성 이 떨 어 지지 만 쿠키 가 없 는 웹 Api 에 서 는 적용 이 매우 간단 하고 편리 하기 때문이다.
Base Authentication 의 가장 큰 단점 은 브 라 우 저 를 닫 을 때 까지 브 라 우 저 캐 시 되 어 있다 는 것 입 니 다. 만약 URI 에 대한 인증 을 받 았 다 면 브 라 우 저 는 권한 수여 헤 어 에 해당 하 는 증 거 를 보 내 서 크로스 사이트 에서 위조 요청 (CSRF) 공격 을 받 기 쉽 습 니 다.
Base Authentication 은 보통 HTTPS 방식 으로 암호 화 처 리 를 해 야 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
작업 중 문제 해결 - (win 2003 asp. net) Session 과 페이지 전송 방법 으로 해결 방안 을 정상적으로 사용 할 수 없습니다.또한 F 는 처음에 우리 의 BP & IT 프로젝트 팀 이 Forms 폼 검증 을 사용 했다 고 판단 할 수 있 습 니 다. 페이지 를 뛰 어 넘 는 것 은http://hr.bingjun.cc/MyTask/MyTas...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.