How to configure libgit2 in TFS Build with private repositories? - tfs

I am currently using TFS 2013 (local installation) to try to build from an internal GitHub Enterprise installation using LDAP Authentication.
The problem I am getting is that it cannot access the source code, how can I configure TFS Build to use a specific authentication?
From the TFS Build Log
Exception Message: An error was raised by libgit2. Category = Net (Error).
VS30063: You are not authorized to access https://user:password#githubrepository.corp.company.net. (type LibGit2SharpException)
Exception Data Dictionary:
libgit2.code = -1
libgit2.category = 11
Exception Stack Trace:
Server stack trace:
at LibGit2Sharp.Core.Ensure.HandleError(Int32 result)
at LibGit2Sharp.Core.Proxy.git_clone(String url, String workdir, GitCloneOptions opts)
at LibGit2Sharp.Repository.Clone(String sourceUrl, String workdirPath, Boolean bare, Boolean checkout, TransferProgressHandler onTransferProgress, CheckoutProgressHandler onCheckoutProgress, Credentials credentials)
at Microsoft.TeamFoundation.Build.Activities.Git.GitPull.GitClone.GetRepository(String repositoryUrl, String workingFolder)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
at System.Func3.EndInvoke(IAsyncResult result)
at Microsoft.TeamFoundation.Build.Activities.Git.GitPull.GitRepositoryBase.EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
at System.Activities.AsyncCodeActivity1.System.Activities.IAsyncCodeActivity.FinishExecution(AsyncCodeActivityContext context, IAsyncResult result)
at System.Activities.AsyncCodeActivity.CompleteAsyncCodeActivityData.CompleteAsyncCodeActivityWorkItem.Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)
Follow up
I have tried the URL params for authentication (example)
https://username:password#domain.com/user/project.git
More Follow up
Completely uninstalled and update to the 2013 RC, error message has been updated as well, as it is different.
I have also tried setting up the build controller to run as an authenticated LDAP user in the github enterprise installation.

Libgit2 does support the url credentials, however TFS build activities for GitPull overrides the default behavior with a Microsoft.TeamFoundation.Build.Activities.Git.TfsSmartSubtransport class for the http and https protocol.
This class unfortunately ignores credentials in the URL and instead tries to retrieve credentials from the registry.
I was able to successfully get a TFS build server to pull source code from a gitlab server using TFS build with the default GitTemplate.12.xaml workflow.
Setup the TFS build's repository URL without any credentials in the URL.
Encrypted your credential's password with the following bit of code. This needs to get run on the build server as the encryption process is specific to the local machine it's executed on.
var password = "your_password";
var bytes = Encoding.Unicode.GetBytes(password);
var bytes2 = ProtectedData.Protect(bytes, null, DataProtectionScope.LocalMachine);
var base64 = Convert.ToBase64String(bytes2);
Add the following registry settings to your build server.
NOTE: The URL in the registry must exactly match the absolute URL of your repository or TFS won't find the credentials.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TeamFoundationServer\12.0\HostedServiceAccounts\Build\http://githubrepository.corp.company.net]
"Microsoft_TFS_UserName"="<username goes here>"
"Microsoft_TFS_Password"="<bas64 encrypted password goes here>"
"Microsoft_TFS_CredentialsType"="Windows"
The only other alternatives to this approach that I could think of is to modify the default workflow and replace the GitPull activity with something else.
I'm not suggesting that this is the best method, but it worked for me.

That's odd. It looks like the HTTP transport should honor url-encoded credentials.
In any case, it might be better and safer to set up the remote to get the credentials from elsewhere. The clone code is a good example of how to do this: here's how to set up the callback, and here's an example of how to generate the credential object.

Related

#WithMockKeycloakAuth get accesstoken as bearer String for mockMvc perform Header

I have one service and Keycloak 11 as Authentication server. Now I want to write tests. To mock the accesstoken, I use #WithMockKeycloakAuth. This works well and I get an unauthorized when I pass a bad role for example. Now I want to document it with spring rest docs the therefor I have to add the acesstoken as header field ( Bearer tokenAsBearerString ). Because of the annotation, the mocked token is added to the SecurityContext and I can extract it before doing the mvc.perform.
#Test
#Order(5)
#WithMockKeycloakAuth(authorities = "ROLE_owner")
void createProduct_RealmRoleOwner_HttpStatusCreated() throws Exception {
SecurityContext context = SecurityContextHolder.getContext();
KeycloakAuthenticationToken authentication =(KeycloakAuthenticationToken) context.getAuthentication();
AccessToken token = authentication.getAccount().getKeycloakSecurityContext().getToken();
The problem is that I need the accesstoken as Bearer string representation. I'm not yet very familiar with the jwt topic but I expected that if I use the mocked acces token and convert it to a jwt format / Base 64 encoded String the header should be correct.
In addition: I'm running a Keycloak container via docker in a seperate network so it is not reachable while I run my automated test. So mocking would be the only solution.
This question was also asked (and answered) here with a little more context.
The code snippet provided above doesn't show that test class is decorated with #AutoConfigureMockMvc(addFilters = false), reason why the security context is not attached to the MockMvc HTTP request (this is normally done by a spring-security filter).
The complete stack trace isn't provided neither, but it's very likely that the exception occurring when filters are enabled is due to JwtDecoder wiring from Keycloak boot lib. #MockBean JwtDecoder jwtDecoder; should be enough to fix it.
Finally, it is one of main features of the lib #WithMockKeycloakAuth is taken from to skip fetching, decoding and parsing an actual JWT from Keycloak instance. Trying to build an authorization header with valid JWT from mocked spring authentication is ...

TFS build failing because of registry access is not allowed

I am configuring New bulid server I am having TFS 2013. I am an admin on the build server and the account which is used for configuring build server is also a admin on build server.
I am able to access my TFS and able to Checkin code as well from build server.
I don't know what access rights I have to give to my user or to the account used for configuring build server.
Exception Message: Requested registry access is not allowed. (type SecurityException)
Exception Stack Trace:
Server stack trace:
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at Microsoft.TeamFoundation.Common.Internal.TeamFoundationEnvironment.OpenOrCreateRootUserRegistryKey()
at Microsoft.TeamFoundation.VersionControl.Client.Workstation.get_AttemptToAutoResolveConflicts()
at Microsoft.TeamFoundation.VersionControl.Client.Client.Get(Workspace workspace, GetRequest[] requests, GetOptions options, GetFilterCallback filterCallback, Object userData, String[] itemAttributeFilters, String[] itemPropertyFilters, Boolean alwaysQueryConflicts, Conflict[]& conflicts, Int32 operationId)
at Microsoft.TeamFoundation.VersionControl.Client.Workspace.Get(GetRequest[] requests, GetOptions options, GetFilterCallback filterCallback, Object userData, String[] itemAttributeFilters, String[] itemPropertyFilters, Boolean alwaysQueryConflicts, Conflict[]& conflicts)
at Microsoft.TeamFoundation.VersionControl.Client.Workspace.Get(GetRequest[] requests, GetOptions options, GetFilterCallback filterCallback, Object userData)
at Microsoft.TeamFoundation.Build.Workflow.Activities.TfGet.TfGetCore.RunCommand(VersionControlScope versionControlScope, Workspace workspace, String getting, String nonFatalError, String version, String fileSpec, GetOptions options, RecursionType recursion)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
at System.Func`9.EndInvoke(IAsyncResult result)
at Microsoft.TeamFoundation.Build.Workflow.Activities.TfGet.TfGetCore.EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
at System.Activities.AsyncCodeActivity`1.System.Activities.IAsyncCodeActivity.FinishExecution(AsyncCodeActivityContext context, IAsyncResult result)
at System.Activities.AsyncCodeActivity.CompleteAsyncCodeActivityData.CompleteAsyncCodeActivityWorkItem.Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)
The service account configured for the build service needs the rights. The TFS service and the build service may or may not be configured to run under the same account. Your personal account is not part of this equation.
MSDN outlines the permissions required for each service account here https://msdn.microsoft.com/en-us/library/ms253149(v=vs.120).aspx Look at the entry for TFSBuild
The setup is also outlined in https://msdn.microsoft.com/en-gb/library/ms181712(v=vs.120).aspx and explains how to pick what type of account you should choose when setting up your build server

How to use cached ticket with KerberosRestTemplate?

I want to implement integration test for my spring security kerberos authentication.
There is KerberosRestTemplate (reference) for this purpose. KerberosRestTemplate has got a default constructor with description "Leave keyTabLocation and userPrincipal empty if you want to use cached ticket".
For research i wrote a trivial class:
public static void main(String[] args) {
KerberosRestTemplate krt = new KerberosRestTemplate();
String result = krt.getForObject("http://testserver.testad.local:8080/", String.class);
System.out.println(result);
}
When i run it, exception has thrown:
Exception in thread "main" org.springframework.web.client.RestClientException: Error running rest call; nested exception is java.lang.IllegalArgumentException: Null name not allowed
at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecute(KerberosRestT
emplate.java:196)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
at edu.mezlogo.Application.main(Application.java:9)
Caused by: java.lang.IllegalArgumentException: Null name not allowed
at sun.security.krb5.PrincipalName.<init>(Unknown Source)
at sun.security.krb5.PrincipalName.<init>(Unknown Source)
at javax.security.auth.kerberos.KerberosPrincipal.<init>(Unknown Source)
at javax.security.auth.kerberos.KerberosPrincipal.<init>(Unknown Source)
at org.springframework.security.kerberos.client.KerberosRestTemplate.doExecute(KerberosRestT
emplate.java:182)
... 3 more
My klist contain correct cached ticket, for my service.
#2> Client: deniz # TESTAD.LOCAL
Server: HTTP/testserver.testad.local # TESTAD.LOCAL
KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)
Ticket Flags 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
Start Time: 2/5/2016 6:17:39 (local)
End Time: 2/5/2016 16:16:32 (local)
Renew Time: 2/12/2016 6:16:32 (local)
Session Key Type: RSADSI RC4-HMAC(NT)
And my browser (firefox) has successful authenticated with kerberos sso.
I use Windows server 2012. And Windows 7 as client.
How to use cached ticket? (And does ktpass can generate client keytab?)
P.s. sorry for my English.
You are checking the Windows credentials cache - while Java is maintaining it's separate. In order to view the Java's credentials cache you should execute the klist command from your JRE/bin folder

TF270016 Error publishing access denied even with correct permissions on drop folder TFS 2013

I am having trouble solving an access denied problem. I've gone through so many posts trying to find a solution and just can't seem to figure out what is going on. I am new to setting up a build server, but I dug through as many sites and instructions as I could to try to understand how to do it. We are using TFS 2013 Express. I installed the Build server components, setting up a Build Controller and a Build agent. Originally I used the default Network Service account but when I ran into some issues, I decided to set up a domain user account for the build service. I removed the controller and then recreated a new controller and agent using the domain user account.
When I try to build a project--my first build definition--I get the following error:
Exception Message: TF270016: An error occurred publishing log files
from 'C:\Builds\5\XYZ\Client\src\DEV\XYZ.log' to
'\myserver\Builds\Client\Client_20141212.4\logs'. Details: Access
to the path '\myserver\Builds\Client\Client_20141212.4\logs' is
denied. (type PublishLogFileException) Exception Stack Trace: at
System.Activities.Statements.Throw.Execute(CodeActivityContext
context) at
System.Activities.CodeActivity.InternalExecute(ActivityInstance
instance, ActivityExecutor executor, BookmarkManager bookmarkManager)
at
System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor
executor, BookmarkManager bookmarkManager, Location resultLocation)
Inner Exception Details:
Exception Message: Access to the path
'\myserver\Builds\Client\Client_20141212.4\logs' is denied. (type
UnauthorizedAccessException) Exception Stack Trace: at
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.Directory.InternalCreateDirectory(String fullPath, String
path, Object dirSecurityObj, Boolean checkHost) at
System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean
checkHost) at
Microsoft.TeamFoundation.Common.FileSpec.CopyFile(String oldPath,
String newPath, Boolean overwriteExisting) at
Microsoft.TeamFoundation.Build.Workflow.Activities.WindowsDropProvider.CopyDirectory(String
sourceDirectory, String targetDirectory) at
Microsoft.TeamFoundation.Build.Workflow.Activities.WindowsDropProvider.CopyDirectory(String
sourceDirectory, String targetDirectory, String[] renameIfExists)
at
Microsoft.TeamFoundation.Build.Workflow.Activities.PublishLogFile.Execute(CodeActivityContext
context)
I know that it appears evident that it's a permissions issue. However, I have verified that the user account I have set up my build service to use has permissions to the \myserver\Builds share. I can log in as that user, connect to the share, and create, edit and delete files. So I'm just not sure what I'm missing here or why I'm still getting the access denied error.
I'd love some feedback other than the typical 'you just need to give permissions to your drop folder to your build service account'.
I just went through this with a customer. The solution in my case was that the build drop location can't be a friendly DNS name.
For example, our server's name was GXDPLTFSBLD1P. We set up a DNS alias for the server to "tfsbuild".
When the build drop location in the build definition was set to \\tfsbuild\drops, we got that error.
When we changed it to \\GXDPLTFSBLD1P\drops, it went away.

Why does XDocument.Load throw exception when ELMAH is enabled?

I have the following code that retrieves a link to the latest post from the blog subsite:
XDocument doc = XDocument.Load("http://www.mysite.com/blog/syndication.axd");
XElement node = doc.Descendants("item").FirstOrDefault();
string text = node.Element("title").Value;
string uri = node.Element("link").Value;
The code always worked fine. This week I added ELMAH.MVC via NuGet as a Package Reference. As soon as I deploy the web.config file with the added ELMAH sections, I get the following error:
System.Web.HttpException (0x80004005): Error executing child request for handler
'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
---> System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
at System.Net.HttpWebRequest.GetResponse()
at System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials, IWebProxy proxy, RequestCachePolicy cachePolicy)
at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials, IWebProxy proxy, RequestCachePolicy cachePolicy)
at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.XmlReaderSettings.CreateReader(String inputUri, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
at System.Xml.Linq.XDocument.Load(String uri, LoadOptions options)
If I put the old web.config file back, the error goes away.
Any idea why adding ELMAH would cause XDocument.Load to fail?
You need to look at your ASP.Net site and find the server-side error.

Resources