diff --git a/routers/repo/http.go b/routers/repo/http.go
index 2f0a707f7c..6b4dec8149 100644
--- a/routers/repo/http.go
+++ b/routers/repo/http.go
@@ -83,85 +83,98 @@ func HTTP(ctx *context.Context) {
 
 	// check access
 	if askAuth {
-		authHead := ctx.Req.Header.Get("Authorization")
-		if len(authHead) == 0 {
-			ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=\".\"")
-			ctx.Error(http.StatusUnauthorized)
-			return
-		}
-
-		auths := strings.Fields(authHead)
-		// currently check basic auth
-		// TODO: support digit auth
-		// FIXME: middlewares/context.go did basic auth check already,
-		// maybe could use that one.
-		if len(auths) != 2 || auths[0] != "Basic" {
-			ctx.HandleText(http.StatusUnauthorized, "no basic auth and digit auth")
-			return
-		}
-		authUsername, authPasswd, err = base.BasicAuthDecode(auths[1])
-		if err != nil {
-			ctx.HandleText(http.StatusUnauthorized, "no basic auth and digit auth")
-			return
-		}
-
-		authUser, err = models.UserSignIn(authUsername, authPasswd)
-		if err != nil {
-			if !models.IsErrUserNotExist(err) {
-				ctx.Handle(http.StatusInternalServerError, "UserSignIn error: %v", err)
+		if setting.Service.EnableReverseProxyAuth {
+			authUsername = ctx.Req.Header.Get(setting.ReverseProxyAuthUser)
+			if len(authUsername) == 0 {
+				ctx.HandleText(401, "reverse proxy login error. authUsername empty")
 				return
 			}
-
-			// Assume username now is a token.
-			token, err := models.GetAccessTokenBySHA(authUsername)
+			authUser, err = models.GetUserByName(authUsername)
 			if err != nil {
-				if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) {
-					ctx.HandleText(http.StatusUnauthorized, "invalid token")
-				} else {
-					ctx.Handle(http.StatusInternalServerError, "GetAccessTokenBySha", err)
-				}
+				ctx.HandleText(401, "reverse proxy login error, got error while running GetUserByName")
+				return
+			}
+		}else{
+			authHead := ctx.Req.Header.Get("Authorization")
+			if len(authHead) == 0 {
+				ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=\".\"")
+				ctx.Error(http.StatusUnauthorized)
 				return
 			}
-			token.Updated = time.Now()
-			if err = models.UpdateAccessToken(token); err != nil {
-				ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err)
+
+			auths := strings.Fields(authHead)
+			// currently check basic auth
+			// TODO: support digit auth
+			// FIXME: middlewares/context.go did basic auth check already,
+			// maybe could use that one.
+			if len(auths) != 2 || auths[0] != "Basic" {
+				ctx.HandleText(http.StatusUnauthorized, "no basic auth and digit auth")
+				return
 			}
-			authUser, err = models.GetUserByID(token.UID)
+			authUsername, authPasswd, err = base.BasicAuthDecode(auths[1])
 			if err != nil {
-				ctx.Handle(http.StatusInternalServerError, "GetUserByID", err)
+				ctx.HandleText(http.StatusUnauthorized, "no basic auth and digit auth")
 				return
 			}
-		}
 
-		if !isPublicPull {
-			var tp = models.AccessModeWrite
-			if isPull {
-				tp = models.AccessModeRead
+			authUser, err = models.UserSignIn(authUsername, authPasswd)
+			if err != nil {
+				if !models.IsErrUserNotExist(err) {
+					ctx.Handle(http.StatusInternalServerError, "UserSignIn error: %v", err)
+					return
+				}
+
+				// Assume username now is a token.
+				token, err := models.GetAccessTokenBySHA(authUsername)
+				if err != nil {
+					if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) {
+						ctx.HandleText(http.StatusUnauthorized, "invalid token")
+					} else {
+						ctx.Handle(http.StatusInternalServerError, "GetAccessTokenBySha", err)
+					}
+					return
+				}
+				token.Updated = time.Now()
+				if err = models.UpdateAccessToken(token); err != nil {
+					ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err)
+				}
+				authUser, err = models.GetUserByID(token.UID)
+				if err != nil {
+					ctx.Handle(http.StatusInternalServerError, "GetUserByID", err)
+					return
+				}
 			}
 
-			has, err := models.HasAccess(authUser, repo, tp)
-			if err != nil {
-				ctx.Handle(http.StatusInternalServerError, "HasAccess", err)
-				return
-			} else if !has {
-				if tp == models.AccessModeRead {
-					has, err = models.HasAccess(authUser, repo, models.AccessModeWrite)
-					if err != nil {
-						ctx.Handle(http.StatusInternalServerError, "HasAccess2", err)
-						return
-					} else if !has {
+			if !isPublicPull {
+				var tp = models.AccessModeWrite
+				if isPull {
+					tp = models.AccessModeRead
+				}
+
+				has, err := models.HasAccess(authUser, repo, tp)
+				if err != nil {
+					ctx.Handle(http.StatusInternalServerError, "HasAccess", err)
+					return
+				} else if !has {
+					if tp == models.AccessModeRead {
+						has, err = models.HasAccess(authUser, repo, models.AccessModeWrite)
+						if err != nil {
+							ctx.Handle(http.StatusInternalServerError, "HasAccess2", err)
+							return
+						} else if !has {
+							ctx.HandleText(http.StatusForbidden, "User permission denied")
+							return
+						}
+					} else {
 						ctx.HandleText(http.StatusForbidden, "User permission denied")
 						return
 					}
-				} else {
-					ctx.HandleText(http.StatusForbidden, "User permission denied")
-					return
 				}
-			}
 
-			if !isPull && repo.IsMirror {
-				ctx.HandleText(http.StatusForbidden, "mirror repository is read-only")
-				return
+				if !isPull && repo.IsMirror {
+					ctx.HandleText(http.StatusForbidden, "mirror repository is read-only")
+					return
+				}
 			}
 		}
 	}